Post number #1097746, ID: 641b1f
|
Here's a shell snippet:
if [ $# -ge 1 ] then printf '%s\n' "$@" else cat fi | while IFS= read -r arg do something -cool -with "$arg" done
Works like charm. You can have positional arguments or pipe into stdin.
Now I want the while loop to run in the current environment instead of a subshell. I try:
mkfifo fifo if [ $# -ge 1 ] then printf '%s\n' "$@" else cat fi >fifo while IFS= read -r arg do something -cool -with "$arg" done <fifo
Post number #1097747, ID: 641b1f
|
doesn't. Why doesn't it work?
Even just
cat >fifo &
doesn't work (I missed a & in the example. It's not the reason)
Post number #1097748, ID: 641b1f
|
Positional args do work though
Post number #1097749, ID: 48705c
|
Because bash has syntax designed by clinicaly insane
Post number #1097750, ID: 641b1f
|
This is not a syntax issue
Post number #1097751, ID: 48705c
|
It always is
Post number #1097752, ID: 641b1f
|
The fact that the while loop does not block means it isn't
Post number #1097754, ID: dd7e66
|
this won't work because the writer blocks waiting for a reader, this is why the subshell approach works (reader is immediately accessible) use process substitution if you must continue on this path, file descriptors are safer than pipes otherwise stop using bash i beg of you
Post number #1097755, ID: 641b1f
|
but I've been using this with jq as in
jq .[] <json >fifo & while read…
and it worked. Should I not do this?
Post number #1097756, ID: 641b1f
|
>>1097754 >this won't work because the writer blocks waiting for a reader, this is why the subshell approach works (reader is immediately accessible)
that is why I run cat in background
>stop using bash i beg of you
This is not bash it's meant to be POSIX shell. I use dash for /bin/sh
Post number #1097757, ID: 641b1f
|
>>1097754 > this won't work because the writer blocks waiting for a reader, this is why the subshell approach works (reader is immediately accessible)
Why does printf work in that case?
Post number #1097760, ID: 641b1f
|
My logic is if it works with a pipe, it should work with a named pipe.
Post number #1097761, ID: c43131
|
is this niggerlicious, or is this divine intellect?
Post number #1097803, ID: 641b1f
|
When we use pipelines stdin of the shell is redirected to the frist pipeline process and stdout is redirected from the last process. When I tried to “do it manually” the automatic redirection did not happen so cat does not read from shell's stdin. The sulution is to duplicate the stdin fd.
Post number #1097804, ID: 641b1f
|
mkfifo fifo exec 4<&0 if [ $# -ge 1 ] then printf '%s\n' "$@" else cat <&4 fi >fifo & while IFS= read -r arg do something -cool -with "$arg" done <fifo
Now cat reads from fd 4 instead of whatever is fd 0 in the background process (probably /dev/null).
Total number of posts: 15,
last modified on:
Thu Jan 1 00:00:00 1780051232
| Here's a shell snippet:
if [ $# -ge 1 ]
then printf '%s\n' "$@"
else cat
fi | while IFS= read -r arg
do
something -cool -with "$arg"
done
Works like charm. You can have positional arguments or pipe into stdin.
Now I want the while loop to run in the current environment instead of a subshell. I try:
mkfifo fifo
if [ $# -ge 1 ]
then printf '%s\n' "$@"
else cat
fi >fifo
while IFS= read -r arg
do
something -cool -with "$arg"
done <fifo