Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 43 |
Nodes: | 6 (0 / 6) |
Uptime: | 108:36:27 |
Calls: | 290 |
Files: | 905 |
Messages: | 76,683 |
On 12.10.2024 03:59, Janis Papanagnou wrote:
It depends on your shell. If you choose Kornshell you won't have that
issue and can write it as you've done with the output as you'd expect.
$ uname -a | read var
$ echo "$var"
Linux [...snip...]
The reason is that the last command in a pipeline will (in Kornshell)
be executed in the "current" shell context.
Interesting hint! I wasn't aware that there are such differences between
the shells.
And indeed, some simple tests seem to work in an interactive
ksh.
Let's see the whole story. For historical reasons, I'm actually using
ksh for almost all scripts instead of bash for interactive use - not
knowing about the fact above.
There, I run command A which is producing output and which is calling sub-command B, also producing output. This works fine.
What I want to achieve is to grab some parts of the output and store it
in a variable but without changing the output on the screen.
So I tried something like
tty=`tty`
A | tee $tty | ... | read var
"tee `tty`" inside the command fails, so I do it outside. The output of
A is still there but B's is gone (because B doesn't know anything about
the "tee"?) and the whole thing doesn't seem to be still working. $var
is empty, though this is a ksh script and the stuff behind "tee" is also working.
To my understanding, the default B can be changed with an option but
when I set it to "B | tee $tty", there's still no output.
AFAIR, "var=`...`" works better but as the primary job is the command
itself and the variable is just a spin-off product, I'd prefer to do the assignment at the end. I believe it looks better then ;) ...
Probably it would also be feasible with some temp files but I try to
avoid them wherever possible.
Happy week-end!
fw
(Specifically I'm unsure about the 'B' and what you mean by "sub-command
B" in your example(s).)
tee $input | read myvar && echo "myvar is $myvar"; input= ; myvar=123456789
grep -o 456 | tee $input ) && echo "myvar is $myvar"; input= ; myvar=123456789
I think you're right. But why doesn't it work in ksh?
I'm still thinking about the difference between "< <(...)" and "<<<
`...`"
On Sat, 12 Oct 2024 17:57:16 +0200, Frank Winkler wrote:
I'm still thinking about the difference between "< <(...)" and "<<<
`...`"
Not sure about the extra “<”,
but “<(«cmd»)” gets substituted with the
name of a file (i.e. not stdin) that the process can open and read to get
the output of «cmd». Similarly “>(«cmd»)” gets substituted with the name
of a file (i.e. not stdout) that the process can open and write to feed
input to waiting «cmd».
[...]
'<(...)' executes the command indicated by '...' and provides a file descriptor, something like '/dev/fd/5', which (being effectively a
filename) can be redirected to the 'read' command.
The shell's 'read' command doesn't read from files but from stdin
So it's no "extra" '<' ...
On Sat, 12 Oct 2024 23:47:34 +0200, Janis Papanagnou wrote:
'<(...)' executes the command indicated by '...' and provides a file
descriptor, something like '/dev/fd/5', which (being effectively a
filename) can be redirected to the 'read' command.
It’s an actual file name. The process treats it as just another filename argument.
The fact that it encodes a file descriptor is something OS-
specific, that only code that wants to create such names (like the shell)
has to worry about.
The shell's 'read' command doesn't read from files but from stdin
It can read from any file currently open for reading.
So it's no "extra" '<' ...
Ah, I see. Instead of “< <(«cmd›)”, you could have just written “0<(«cmd»)”.
1) "command2 <<<`command1`": `command2`, equal to the preferable[*] $(command2),
I'm still thinking about the difference between "< <(...)" and "<<<`...`"
And I would be happy with this one if there was a notation "the other
way round" ... something like "... >>> $var"
As already pointed out by Lawrence:
On Sat, 12 Oct 2024 03:59:49 +0200, Janis Papanagnou wrote:
... use bash-specifics like 'coproc' ...
It isn't bash-specific.
On Fri, 11 Oct 2024 22:50:10 +0200, Frank Winkler wrote:
... but it still doesn't solve the issue that I need the result to be
visible in the parent shell.
coproc { uname -sr; }
read -u ${COPROC[0]} var3
wait $COPROC_PID
echo $var3
But my command doesn't work instead, in bash. That's why:
| lastpipe
| If set, and job control is not active, the shell runs the last command
| of a pipeline not executed in the background in the current shell
| environment.
(In other shells you have to work around the issue as demonstrated in
other answers to your post. Some workaround are more clumsy some less.
A shorter variant of the here-document posted elsethread can be using >here-strings
$ read var <<< $(uname -a)
another method is using process substitution and redirection
$ read var < <(uname -a)
Both supported by shells like ksh, bash, zsh, but non-standard as are
some other workaround proposals that use bash-specifics like 'coproc',
that doesn't work as widely as using '<<<' or '<(...)' do.)
In article <vec3qb$3q4ms$3@dont-email.me>,
Lawrence D'Oliveiro <ldo@nz.invalid> wrote:
On Fri, 11 Oct 2024 22:50:10 +0200, Frank Winkler wrote:
... but it still doesn't solve the issue that I need the result to be
visible in the parent shell.
coproc { uname -sr; }
read -u ${COPROC[0]} var3
wait $COPROC_PID
echo $var3
I'm actually a fan of "coproc" in bash, and I use it in my scripting, but I think it is overkill in most cases. [...]
In article <vecmp3$pur$1@dont-email.me>,
Lawrence D'Oliveiro <ldo@nz.invalid> wrote:
On Sat, 12 Oct 2024 03:59:49 +0200, Janis Papanagnou wrote:
... use bash-specifics like 'coproc' ...
It isn't bash-specific.
People on these newsgroups often use phrases like "bash specific" as
synonyms for "Not strictly POSIX" (*), even though the bash feature under discussion is also found in other shells. In fact, many bash-isms,
including "coproc", came originally from ksh. I'm sure Janis knows this.
AFAICT, "lastpipe" (bash)
works in a script, but not interactively.
Also, if above code is how to use co-processes in Bash, I consider that extremely clumsy (if compared to, say, Ksh).
On Sat, 19 Oct 2024 14:52:01 +0200, Janis Papanagnou wrote:
Also, if above code is how to use co-processes in Bash, I consider that
extremely clumsy (if compared to, say, Ksh).
Bash allows for named coprocs. That means you can have multiple coprocs
going at once.
In article <vf1942$1uso$1@dont-email.me>,
Lawrence D'Oliveiro <ldo@nz.invalid> wrote:
On Sat, 19 Oct 2024 14:52:01 +0200, Janis Papanagnou wrote:
Also, if above code is how to use co-processes in Bash, I consider that
extremely clumsy (if compared to, say, Ksh).
"extremely" seems more than a bit over the top. Maybe somewhat clumsy, but hardly "extremely".
Bash allows for named coprocs. That means you can have multiple coprocs
going at once.
[...]
But, yes, that's part of the point of making it possible to assign a name
to a coproc (instead of just taking the default of "coproc").
On 15.10.2024 13:46, I wrote:
The thing in question does
tty=`tty`
sudo openconnect -b ... |\
tee $tty | grep "^Session authentication will expire at" |\
cut -d ' ' -f 7- | read end
and this completely fails. Terminal output is missing, $end is empty and
the whole command doesn't seem to work. Without the last two lines, it's
working perfectly.
"sudo" also doesn't seem to be the problem as simple tests are working.
Maybe some effect of the background option?
echo $end|
echo $endPOST
On 24.10.2024 13:21, Kenny McCormack wrote:
I'm going to assume bash, but there isn't much difference. Inparticular,
note that $() is POSIX, so you really don't need to ever mess with ``.
I know that "$()" is POSIX but I don't feel "``" as a mess but in fact,
I like it much better. And we're talking about ksh.
[...]
I also know that the "``" thing should and does do it but I explicitly
asked why the "read" approach fails and that I'd prefer a solution with
the assignment at the end.
[...]
| $ openconnect -b unresponsive:local:ip:address | tee | grep .
Note that "tee" when run with no args is a no-op.
Hi there !
Consider the following commands:
$ var1=`uname -sr`
$ echo $var1
Darwin 24.0.0
$ read var2 <<< `uname -sr`
$ echo $var2
Darwin 24.0.0
$ uname -sr | read var3
$ echo $var3
$ uname -sr | read -p var3
$ echo $var3
$
While the first two ones behave like expected, I wonder why the latter
ones fail. What's the difference behind the scenes?
And even more confusing, why does this familiar one work anyway?
$ sw_vers | while read line; do echo $line; done
ProductName: macOS
ProductVersion: 15.0.1
BuildVersion: 24A348
Hi there !
Consider the following commands:
$ var1=`uname -sr`
$ echo $var1
Darwin 24.0.0
$ read var2 <<< `uname -sr`
$ echo $var2
Darwin 24.0.0
$ uname -sr | read var3
$ echo $var3
$ uname -sr | read -p var3
$ echo $var3
$
While the first two ones behave like expected, I wonder why the
latter ones fail. What's the difference behind the scenes?
And even more confusing, why does this familiar one work anyway?
$ sw_vers | while read line; do echo $line; done
ProductName: macOS
ProductVersion: 15.0.1
BuildVersion: 24A348
$
I've been using commands like that one for a very long time and
that's why I tried the simple "read" above - with no success.
How can I do such an assignment at the end of a command instead
of the beginning? Any ideas?
... but it still doesn't solve the issue that I need the result to be
visible in the parent shell.
$ uname -sr | ( read var3; echo $var3 )
Darwin 24.0.0
$
... but it still doesn't solve the issue that I need the result to be
visible in the parent shell.
On 11.10.2024 20:27, John-Paul Stewart wrote:
I don't know about other shells, but in Bash each command in a pipeline
is run in a subshell. (See the "Pipelines" section of the Bash man
page.) Thus you're doing the 'read var3' part in a different shell than
where 'echo $var3' runs. That's why it is empty when you echo it.
That sounds very plausible - thanks for enlighting! :)
So this is not a "read" issue but rather a matter of shell instance and
hence there's no way to do the assignment at the end?
... use bash-specifics like 'coproc' ...
AFAIR, "var=`...`" works ...
uname -sr | { read var3 ; echo $var3 ; }
In article <83y12u2xyt.fsf@helmutwaitzmann.news.arcor.de>,
Helmut Waitzmann <oe.throttle@xoxy.net> wrote:
...
More simply;
uname -sr | { read var3 ; echo $var3 ; }
uname -sr