* Re: Capture stdout, stdin, and exit status in different variables without using temporary files
[not found] <D639E5A6-A28C-40EE-B0E6-27BED4C8CDDB__31117.9253900022$1565917892$gmane$org@icloud.com>
2019-08-16 7:22 ` Capture stdout, stdin, and exit status in different variables without using temporary files Stephane Chazelas
@ 2019-08-16 10:05 ` Stephane Chazelas
2019-08-16 10:45 ` Aryn Starr
1 sibling, 1 reply; 7+ messages in thread
From: Stephane Chazelas @ 2019-08-16 10:05 UTC (permalink / raw)
To: Aryn Starr; +Cc: zsh-users
I assume you meant stderr and not stdin which would make little
sense. And the bash wiki pages refers to capturing both stdout
and err, not stdin (whatever that means).
2019-08-15 20:22:38 +0430, Aryn Starr:
> If not, is a named pipe advantageous to a temporary file?
With named pipes, you'd get deadlocks unless you use a
select()/poll() loop like for unnamed pipes.
> Is there a way to avoid disk IO (which will probably slow things down considerably)?
To expand on the solution in the link I gave earlier to also
capture the exit status, that would be:
<<
#! /bin/zsh -
zmodload zsh/zselect
zmodload zsh/system
(){exec {wo}>$1 {ro}<$1} <(:) # like yash's wo>>|ro (but on Linux only)
(){exec {we}>$1 {re}<$1} <(:)
# the command (here ls as an example)
ls -d / /x >&$wo 2>&$we & pid=$!
exec {wo}>&- {we}>&-
out= err=
o_done=0 e_done=0
while ((! (o_done && e_done))) && zselect -A ready $ro $re; do
if ((${#ready[$ro]})); then
sysread -i $ro && out+=$REPLY || o_done=1
fi
if ((${#ready[$re]})); then
sysread -i $re && err+=$REPLY || e_done=1
fi
done
wait "$pid"; exit_status=$?
printf '%s: %s\n' stdout "$out" stderr "$err" 'exit status' "$exit_status"
>>
Which gives:
stdout: /
stderr: ls: cannot access '/x': No such file or directory
exit status: 2
(note that in $out and $err, the trailing newline character is
not removed).
--
Stephane
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Capture stdout, stdin, and exit status in different variables without using temporary files
2019-08-16 10:05 ` Stephane Chazelas
@ 2019-08-16 10:45 ` Aryn Starr
2019-08-16 13:01 ` TJ Luoma
0 siblings, 1 reply; 7+ messages in thread
From: Aryn Starr @ 2019-08-16 10:45 UTC (permalink / raw)
To: Stephane Chazelas; +Cc: zsh-users
Thanks! I read those links and reached two conclusions: That I should this `yash` out. And that I should look for ways to create files on memory.
(I meant stderr, \(ᵔᵕᵔ)/ )
> On Aug 16, 2019, at 2:35 PM, Stephane Chazelas <stephane.chazelas@gmail.com> wrote:
>
> I assume you meant stderr and not stdin which would make little
> sense. And the bash wiki pages refers to capturing both stdout
> and err, not stdin (whatever that means).
>
> 2019-08-15 20:22:38 +0430, Aryn Starr:
>> If not, is a named pipe advantageous to a temporary file?
>
> With named pipes, you'd get deadlocks unless you use a
> select()/poll() loop like for unnamed pipes.
>
>> Is there a way to avoid disk IO (which will probably slow things down considerably)?
>
> To expand on the solution in the link I gave earlier to also
> capture the exit status, that would be:
>
> <<
> #! /bin/zsh -
> zmodload zsh/zselect
> zmodload zsh/system
>
> (){exec {wo}>$1 {ro}<$1} <(:) # like yash's wo>>|ro (but on Linux only)
> (){exec {we}>$1 {re}<$1} <(:)
>
> # the command (here ls as an example)
> ls -d / /x >&$wo 2>&$we & pid=$!
>
> exec {wo}>&- {we}>&-
> out= err=
> o_done=0 e_done=0
>
> while ((! (o_done && e_done))) && zselect -A ready $ro $re; do
> if ((${#ready[$ro]})); then
> sysread -i $ro && out+=$REPLY || o_done=1
> fi
> if ((${#ready[$re]})); then
> sysread -i $re && err+=$REPLY || e_done=1
> fi
> done
> wait "$pid"; exit_status=$?
>
> printf '%s: %s\n' stdout "$out" stderr "$err" 'exit status' "$exit_status"
>>>
>
> Which gives:
>
> stdout: /
>
> stderr: ls: cannot access '/x': No such file or directory
>
> exit status: 2
>
> (note that in $out and $err, the trailing newline character is
> not removed).
>
> --
> Stephane
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Capture stdout, stdin, and exit status in different variables without using temporary files
2019-08-16 10:45 ` Aryn Starr
@ 2019-08-16 13:01 ` TJ Luoma
2019-08-16 13:16 ` Roman Perepelitsa
0 siblings, 1 reply; 7+ messages in thread
From: TJ Luoma @ 2019-08-16 13:01 UTC (permalink / raw)
To: Aryn Starr; +Cc: Zsh MailingList
I have used this, which I am sure someone on the zsh probably gave me:
(){ STDOUT=$( your-command-here 2> $1) STDERR=$(<$1);} =(:)
Using an actual example… I know that `find -x / -maxdepth 4 -print`
will provide both kinds of output, so if I use that here:
(){ STDOUT=$( find -x / -maxdepth 4 -print 2> $1) STDERR=$(<$1);} =(:)
then I can use $STDOUT and $STDERR to get the respective outputs.
I hope that helps!
Tj
--
TJ Luoma
TJ @ MacStories
Personal Website: luo.ma (aka RhymesWithDiploma.com)
Twitter: @tjluoma
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Capture stdout, stdin, and exit status in different variables without using temporary files
2019-08-16 13:01 ` TJ Luoma
@ 2019-08-16 13:16 ` Roman Perepelitsa
2019-08-16 17:08 ` TJ Luoma
0 siblings, 1 reply; 7+ messages in thread
From: Roman Perepelitsa @ 2019-08-16 13:16 UTC (permalink / raw)
To: TJ Luoma; +Cc: Aryn Starr, Zsh MailingList
[-- Attachment #1: Type: text/plain, Size: 748 bytes --]
On Fri, Aug 16, 2019 at 3:03 PM TJ Luoma <luomat@gmail.com> wrote:
> I have used this, which I am sure someone on the zsh probably gave me:
>
> (){ STDOUT=$( your-command-here 2> $1) STDERR=$(<$1);} =(:)
>
The OP is asking for a solution that doesn't use temporary files, so this
doesn't fit.
FWIW, this recipe is what I use when I need to capture stdout and stderr.
It works great. On modern Linux distros /tmp is usually on an in-memory
filesystem, so no disk IO happens when you are using temporary files. Even
when you have to hit disk, modern SSDs are very fast, with read/write
speeds over 3GB per second. Having sequential SSD reads/writes as a
bottleneck is a tough task even for C code and virtually impossible for zsh
scripts.
Roman.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Capture stdout, stdin, and exit status in different variables without using temporary files
2019-08-16 13:16 ` Roman Perepelitsa
@ 2019-08-16 17:08 ` TJ Luoma
0 siblings, 0 replies; 7+ messages in thread
From: TJ Luoma @ 2019-08-16 17:08 UTC (permalink / raw)
To: Roman Perepelitsa; +Cc: Aryn Starr, Zsh MailingList
>> (){ STDOUT=$( your-command-here 2> $1) STDERR=$(<$1);} =(:)
>
> The OP is asking for a solution that doesn't use temporary files, so this doesn't fit.
My apologies, I didn't realize that this method used temporary files.
TjL
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Capture stdout, stdin, and exit status in different variables without using temporary files
[not found] <D639E5A6-A28C-40EE-B0E6-27BED4C8CDDB__31117.9253900022$1565917892$gmane$org@icloud.com>
@ 2019-08-16 7:22 ` Stephane Chazelas
2019-08-16 10:05 ` Stephane Chazelas
1 sibling, 0 replies; 7+ messages in thread
From: Stephane Chazelas @ 2019-08-16 7:22 UTC (permalink / raw)
To: Aryn Starr; +Cc: zsh-users
2019-08-15 20:22:38 +0430, Aryn Starr:
> Per http://mywiki.wooledge.org/BashFAQ/002, it seems this can not be done in bash. Is it possible in zsh?
> If not, is a named pipe advantageous to a temporary file?
> Is there a way to avoid disk IO (which will probably slow things down considerably)?
See
https://unix.stackexchange.com/questions/472585/read-write-to-the-same-file-descriptor-with-shell-redirection/473402#473402
(and
https://unix.stackexchange.com/questions/430161/redirect-stderr-and-stdout-to-different-variables-without-temporary-files
)
Redirecting to files doesn't necessarily mean disk I/O.
--
Stephane
^ permalink raw reply [flat|nested] 7+ messages in thread
* Capture stdout, stdin, and exit status in different variables without using temporary files
@ 2019-08-15 15:52 Aryn Starr
0 siblings, 0 replies; 7+ messages in thread
From: Aryn Starr @ 2019-08-15 15:52 UTC (permalink / raw)
To: zsh-users
[-- Attachment #1: Type: text/plain, Size: 250 bytes --]
Per http://mywiki.wooledge.org/BashFAQ/002, it seems this can not be done in bash. Is it possible in zsh?
If not, is a named pipe advantageous to a temporary file?
Is there a way to avoid disk IO (which will probably slow things down considerably)?
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2019-08-16 17:10 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <D639E5A6-A28C-40EE-B0E6-27BED4C8CDDB__31117.9253900022$1565917892$gmane$org@icloud.com>
2019-08-16 7:22 ` Capture stdout, stdin, and exit status in different variables without using temporary files Stephane Chazelas
2019-08-16 10:05 ` Stephane Chazelas
2019-08-16 10:45 ` Aryn Starr
2019-08-16 13:01 ` TJ Luoma
2019-08-16 13:16 ` Roman Perepelitsa
2019-08-16 17:08 ` TJ Luoma
2019-08-15 15:52 Aryn Starr
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).