So i have that script to which i'd like to pipe (rather than just regular arguments) some data from another virtual output command.
Simplified:
echo * | script.sh
When i know how many args i expect, i can handle this simple by:
[ -z "$@" ] && \
read ONE TWO && \
set ONE TWO
echo "$1 : $2
But how would i approach to get an unknown number of arguments?
Any ideas please?
EDIT
Oh yeah, given the asterix example, i expect some values to be strings with spaces, which should remain preserved.
Otherwise i'd already have tried:
read ARGS
ARRAY=( echo $ARGS )
Thank you in advance
---------- Post updated at 03:54 ---------- Previous update was at 03:48 ----------
In cases like this, echo is your enemy. The shell removes the quotes as it processes arguments it passes to echo and when read sees the echo output on the other side of the pipe, it can't determine which blanks are supposed to be argument separators and which are supposed to be data in an argument.
If you are trying to maintain variable boundaries in arguments passed to a shell, passing those arguments as command-line arguments will always be easier than trying to reconstruct argument boundaries read through a pipeline.
If you must pass parameters though a pipeline, you have to choose a character (or string) that can never appear in any string to want to treat as a variable as your field separator instead of using the default IFS=<space><tab><newline> as field separators.
The difference isnt that bad, given the read its timeout is limited only to 2nd position of post decimal indicator.
#
# Testing simple
#
declare -a ARRAY
if [ "$1" = "" ]
then while read -t 0.01 ARG
do ARRAY[${#ARRAY[@]}]="$ARG"
done
else ARRAY=( "${@}" )
fi
#
# Parsing input
#
for item in "${ARRAY[@]}"
do echo "something with $item"
done
0 ~/tmp $ time ./get-pipe.sh *
something with browser
something with get-pipe.sh
something with get-pipe-test.sh
something with test with spaces
real 0m0.002s
user 0m0.001s
sys 0m0.001s
0 ~/tmp $ time ls | ./get-pipe.sh
something with browser
something with get-pipe.sh
something with get-pipe-test.sh
something with test with spaces
real 0m0.002s
user 0m0.003s
sys 0m0.001s
Thank you and hope this helps
---------- Post updated at 06:29 ---------- Previous update was at 06:04 ----------
Now i tried to remove the array, and shorten it a bit, now it behaves weird.
[ -z "$1" ] && \
while read ARG
do set "$ARG"
done
for item in "${@}"
do echo "something with $item"
done
0 ~/tmp $ ./get-pipe.sh *
something with browser
something with get-pipe.sh
something with get-pipe-test.sh
something with test with spaces
0 ~/tmp $ ls | ./get-pipe.sh
something with test with spaces
0 ~/tmp $
Even with while IFS="$IFS\l" read ARG there was no difference.
Any ideas please?
Thank you, thats working great for single line outputs, even for the list.
But when i try to 'combine' it with another read, it starts with an endless loop, kind of...
Now, the list works fine with piped input:
...
removed codes as it seemed mislead in my question
...
The lsof s are in there to show the file descriptor has been bequeathed. This is just an idea/a proposal, not the slightest idea how resilient and error proof it is...
#
# Testing simple
#
[ -z "$1" ] && \
while IFS= read -r ARG
do set -- "$@" "$ARG"
done
#
# Parsing input
#
for item in "${@}"
do echo "$item"
read -N 1 -p "Is that correct (y/n)" USERINPUT
done
1 ~/tmp $ ls | ./get-pipe.sh
browser
get-pipe.sh
get-pipe-test.sh
test with spaces
1 ~/tmp $ ./get-pipe.sh *
browser
Is that correct (y/n)yget-pipe.sh
Is that correct (y/n)yget-pipe-test.sh
Is that correct (y/n)ytest with spaces
Is that correct (y/n)y
---------- Post updated at 21:07 ---------- Previous update was at 20:09 ----------
Updated and Redcued code.
I didnt handle the read input, as its not getting there with the pipe anyway.
I do want the argument behaviour also for the pipe, printing the question and letting the user type something.
Thank you in advance
EDIT:
So its actualy all about getting the USERINPUT from the read command.
your stdin isn't the tty anymore, it's a pipe... you can try opening the tty directly again:
mute@tiny:~$ printf %s\\n one 'two foo' 3 | ( while read file; do printf 'use [[%s]]? ' "$file"; read </dev/tty; [[ $REPLY = [Yy]* ]] || continue; echo "okay i'll use $file"; done; )
use [[one]]? n
use [[two foo]]? y
okay i'll use two foo
use [[3]]? n