[BASH] Read pipe of unkown number of arguments?


 
Thread Tools Search this Thread
Top Forums UNIX for Advanced & Expert Users [BASH] Read pipe of unkown number of arguments?
# 1  
Old 06-02-2015
[BASH] Read pipe of unkown number of arguments?

Heays

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:
Code:
echo * | script.sh

When i know how many args i expect, i can handle this simple by:
Code:
[ -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:
Code:
read ARGS
ARRAY=( echo $ARGS )

Thank you in advance

---------- Post updated at 03:54 ---------- Previous update was at 03:48 ----------

Just tried, but i knew it wouldnt work:
Code:
echo "a b" c | ./get-pipe.sh 

a
b

Code:
	read ARGS
	ARRAY=( ${ARGS[@]} )
	echo "${ARRAY[0]}"
	echo "${ARRAY[1]}"

NOTE: If i'd quote the ARRAY=ARGS statement, i'd get all vars on one line..
# 2  
Old 06-03-2015
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.
This User Gave Thanks to Don Cragun For This Post:
# 3  
Old 06-03-2015
Thank you Don!
Figured Smilie

The difference isnt that bad, given the read its timeout is limited only to 2nd position of post decimal indicator. Smilie
Code:
#
#	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

Code:
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.
Code:
[ -z "$1" ] && \
	while read  ARG
	do	set "$ARG"
	done
for item in "${@}"
do	echo "something with $item"
done

Code:
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?

(edit: Or should i better stay with the array?)

Last edited by sea; 06-03-2015 at 01:34 AM.. Reason: Code fix
# 4  
Old 06-03-2015
Quote:
Originally Posted by sea
... ... ...

Now i tried to remove the array, and shorten it a bit, now it behaves weird.
Code:
[ -z "$1" ] && \
	while read  ARG
	do	set "$ARG"
	done
for item in "${@}"
do	echo "something with $item"
done

Code:
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?

(edit: Or should i better stay with the array?)
Not weird at all. Every time through the read loop, set clears all of the arguments you have accumulated. Try something more like:
Code:
if [ $# -eq 0 ]
then	while IFS= read -r ARG
	do	set -- "$@" "$ARG"
	done
fi
printf 'Arg count: %d\n' $#
printf '\targ: "%s"\n' "$@"

But, this still won't work if you have an argument that has embedded <newline> characters.
This User Gave Thanks to Don Cragun For This Post:
# 5  
Old 06-03-2015
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:
Code:
...
removed codes as it seemed mislead in my question
...

Any ideas please?
Thank you in advance.

Last edited by sea; 06-03-2015 at 04:12 PM..
# 6  
Old 06-03-2015
Not sure I understand to full extent what you need, but reading a pipe and then switching back to terminal input could be done like this:
Code:
( exec 3<&0; { lsof -p$BASHPID ; echo bla; } | { lsof -p$BASHPID; cat;  exec 0<&3; read AB; echo $AB; } )

The lsofs 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...
# 7  
Old 06-03-2015
Sorry, should have reduced.

Code:
#
#	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

Code:
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.

Last edited by sea; 06-03-2015 at 04:15 PM.. Reason: replaced content
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Cat a script, pipe it, then pass arguments to it?

suppose i have a perl script that is normally run this way: ./checkdisk.pl -H hostname -w 40 -c 80 but, for whatever reason, i cannot run the script directly as it should. But i can cat it through pipe. How can i pass the arguments "-H hostname -w 40 -c 80"? so this is what i'm doing,... (6 Replies)
Discussion started by: SkySmart
6 Replies

2. Shell Programming and Scripting

Function in one-linef and pass arguments in a pipe

I need to declare a function, this function will contain a script, this script cannot be in a file but must be piped. and then, for the script to run, i need to pass arguments to it. everything has to be on one line. so i'm basically looking for a one-liner here's what i'm doing: myfunc ()... (3 Replies)
Discussion started by: SkySmart
3 Replies

3. Shell Programming and Scripting

If number of arguments =$ or $

Hi, I am having a bit of trouble writing this. I have the script working if I only use 1 of these but it's not working the way i need it to. Basically more above the script i may or may not have a 5th variable defined. if i do it does a process before getting to the rest of the script.... (2 Replies)
Discussion started by: techy1
2 Replies

4. Shell Programming and Scripting

Multiple arguments to read

I am developing a script where 3 other scripts are included. This is a graph related script. COMPLETE IDEA: -There are 3 different graph scripts. I would like to create a master graph with all 3 in one. -User chooses the type of graph -User is asked to enter the required auguments (... (7 Replies)
Discussion started by: newkid.7955
7 Replies

5. Shell Programming and Scripting

Bash Script Help...search then read from file: change text and pipe back...

Hello, I am trying to make a bash script that can pull data from a file and then change one part of said data. I want to search by username and pull the full line. That way there is a way to replace just one part of that line then return it back to the file. My Data is stored like: ... (1 Reply)
Discussion started by: serverfull
1 Replies

6. Shell Programming and Scripting

bash read within function with arguments

I have trouble getting this logic to work #!/bin/bash function assign_var(){ while do read -p "$2 :" $3 done } assign_var '$IPADDRESS' ipaddress IPADDRESS Basicly, i want to make sure that entry is made (i can add more sophisticated checks later), but the idea is to recycle... (11 Replies)
Discussion started by: serverchief
11 Replies

7. Homework & Coursework Questions

checking for number of arguments.

Use and complete the template provided. The entire template must be completed. If you don't, your post may be deleted! 1. The problem statement, all variables and given/known data: Your script must check for the correct number of arguments (one argument). If somebody tries to invoke the... (1 Reply)
Discussion started by: brooksie91
1 Replies

8. UNIX for Dummies Questions & Answers

maximum number of arguments

Hi, What is the maximum number of arguments that could be passed to zsh ? To find out that I tried a simple script. And the maximum number of arguments that could be passed turned out to be 23394 #! /bin/zsh arg=1 i=1 subIndex=23000 while do arg=$arg" "$i i=$(($i + 1))... (9 Replies)
Discussion started by: matrixmadhan
9 Replies

9. Programming

read arguments from shell

I have to write a C program using sys call (read, no fread) to read from shell all the parameters, without know how many are them. I tryed in some ways, but I have no success. Any Idea? Can I use read to read from stdin? (1 Reply)
Discussion started by: DNAx86
1 Replies

10. Shell Programming and Scripting

read number of arguments in c shell

I am writing script in c shell and using this script to read the command line arguments, but it is not working. Pl. someone let me know what is the problem. #!/bin/csh -f if ($#argv <> 2) then echo "you must give exactly two parameters" else set name1 = $argv ... (1 Reply)
Discussion started by: skumar11
1 Replies
Login or Register to Ask a Question