Pipe input into a script Pipe input into a script unix unix

Pipe input into a script


Commands inherit their standard input from the process that starts them. In your case, your script provides its standard input for each command that it runs. A simple example script:

#!/bin/bashcat > foo.txt

Piping data into your shell script causes cat to read that data, since cat inherits its standard input from your script.

$ echo "Hello world" | myscript.sh$ cat foo.txtHello world

The read command is provided by the shell for reading text from standard input into a shell variable if you don't have another command to read or process your script's standard input.

#!/bin/bashread fooecho "You entered '$foo'"$ echo bob | myscript.shYou entered 'bob'


There is one problem here. If you run the script without first checking to ensure there is input on stdin, then it will hang till something is typed.

So, to get around this, you can check to ensure there is stdin first, and if not, then use a command line argument instead if given.

Create a script called "testPipe.sh"

#!/bin/bash# Check to see if a pipe exists on stdin.if [ -p /dev/stdin ]; then        echo "Data was piped to this script!"        # If we want to read the input line by line        while IFS= read line; do                echo "Line: ${line}"        done        # Or if we want to simply grab all the data, we can simply use cat instead        # catelse        echo "No input was found on stdin, skipping!"        # Checking to ensure a filename was specified and that it exists        if [ -f "$1" ]; then                echo "Filename specified: ${1}"                echo "Doing things now.."        else                echo "No input given!"        fifi

Then to test:

Let's add some stuff to a test.txt file and then pipe the output to our script.

printf "stuff\nmore stuff\n" > test.txtcat test.txt | ./testPipe.sh

Output:Data was piped to this script!Line: stuff Line: more stuff

Now let's test if not providing any input:

./testPipe.sh

Output:No input was found on stdin, skipping!No input given!

Now let's test if providing a valid filename:

./testPipe.sh test.txt

Output:No input was found on stdin, skipping!Filename specified: test.txtDoing things now..

And finally, let's test using an invalid filename:

./testPipe.sh invalidFile.txt

Output:No input was found on stdin, skipping!No input given!

Explanation: Programs like read and cat will use the stdin if it is available within the shell, otherwise they will wait for input.

Credit goes to Mike from this page in his answer showing how to check for stdin input: https://unix.stackexchange.com/questions/33049/check-if-pipe-is-empty-and-run-a-command-on-the-data-if-it-isnt?newreg=fb5b291531dd4100837b12bc1836456f


If the external program (that you are scripting) already takes input from stdin, your script does not need to do anything. For example, awk reads from stdin, so a short script to count words per line:

#!/bin/shawk '{print NF}'

Then

./myscript.sh <<ENDoneone twoone two threeEND

outputs

123