How to use stdin as argument for script?

Say I had an extremely simple script called testScript.sh:

#!/bin/sh
echo $1

and I invoked it as:

source testScript.sh <<< x

or

source testScript.sh <<< inputFile.txt

When I do the above the values don't appear in the echo statement, and I know that is because in the echo statement I am referring to an argument.

How can I get the value from stdin to be used as an argument to be used in the script. Or how can I invoke it as above and use the stdin value or values in the script?

Most all of the solutions I've looked up use the constructs "read", "exec" or "/dev/stdin" as a solution but in this scenario how would I do it without using the above solutions? How can I use the values passed in from stdin?

Thanks.

Hi,

You mean like this ?

cat test.sh
echo $1

./test.sh x
x

or

./test.sh <<< echo "x"

Is this what you are after:-
This is not 'source'd as such as source serves no purpose here.
Also here strings and the word 'source' are undefined inside a POSIX shell.

#!/bin/sh
# source_test.sh
echo "$1"

Being called to get "$1"...

#!/bin/sh
# source_call.sh
y=$( ./source_test.sh "AMIGA A1200..." )
echo "Looking for computer, $y"

Results on OSX 10.12.1, default bash terminal...

Last login: Mon Dec  5 22:00:27 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> chmod 755 source_test.sh
AMIGA:amiga~/Desktop/Code/Shell> chmod 755 source_call.sh
AMIGA:amiga~/Desktop/Code/Shell> ./source_call.sh
Looking for computer, AMIGA A1200...
AMIGA:amiga~/Desktop/Code/Shell> _

Why would you use stdin as an argument to the script? stdin by default is available to the script UNLESS explicitly closed. Use redirection to process files or other streams in your script.

echo asdf | xargs ./myscript.sh

Sorry to say that but i think this example is badly constructed: what you do is not to feed the shell scripts <stdin> but to use xargs to transform xargs <stdin> to (positional) arguments on the scripts commandline. In fact, your example amounts to the same as issuing

./myscript.sh asdf

from the beginning.

Back to the original question of the thread: the confusion is about what constitues "input" to a process (or, in this case, a script).

Let us start with a picture: think of a process like a garden hose: you pour something in on top (stdin) and something comes out at the bottom (stdout). There is also a second outlet to this hose (stderr), but let us ignore that for now.

In this picture the pipe symbol is like a connector: you connect the bottom of one hose with the top of the other. Now, normal garden hoses just let out what goes in, but UNIX processes act differently: they transform what is running through them. To stay in the picture: say, one hose will turn red water into green water, another will turn water of any colour into oil of the same colour. If you need green oil but only have red water, you pour it through the "red-water-to-green-water"-hose first and what comes out of through the "water-to-oil"-hose":

<red-water-generating process> | rw2gw | w2oil 

Commandline options in this picture are the control panel each of these hoses has: some knobs to steer its function, but all this is separate from the data that flows through this process. Your stereo system might have some controls (for volume, treble, basses, ...) to influence the way how what you play is played, but as long as you do not change the CD you always hear the same music.

Now, after this long introduction, what does your script: $1 ( $2 , $3 , ...) are placeholders for so-called positional parameters: commandline arguments you provide when you call the script. Consider the following command:

./foo.sh abc def "xy zz" 123

When this is executed the shell interprets the command, separating "words" which are delimited by spaces (with the notable exception of "xy zz" because of the quotation marks, which counts as one word) and each of these "words" are represented by "$n" inside the script:

$1: abc
$2: def
$3: xy zz
$4: 123

But all this is just putting different control knobs onto the control panel of the script. Let us process now data - the stuff that flows through the hose:

#! /bin/ksh

while read LINE ; do
     echo "+++ $LINE +++"
done

exit 0

Call this with:

./script.sh < /some/inputfile

And you will see the content of /some/inputfile eclosed in some plus characters.

How does this work? The command read <variable> will read from <stdin> and assign a read line to a variable (in this case "$LINE"). As long is input is provided, read will return a 0 and the while-loop will continue. Once there is no moe input read will return non-0 and the while-loop will exit.

Inside the loop. as long as it is running, we simply output the line we have just read and decorate it with the plus signs (just to show that we have been there and really have processed it).

I hope this helps.

bakunin