74

Suppose I have a bash shell script called Myscript.sh that need one argument as input.

But I want the content of the text file called text.txt to be that argument.

I have tried this but it does not work:

cat text.txt | ./Myscript.sh

Is there a way to do this?

Narin
  • 843

9 Answers9

73

You can use pipe output as a shell script argument.

Try this method:

cat text.txt | xargs -I {} ./Myscript.sh {}
mic84
  • 2,413
zzart
  • 831
51

Command substitution.

./Myscript.sh "$(cat text.txt)"
8

To complete @bac0n which IMHO is the only one to correctly answers the question, here is a short-liner which will prepend piped arguments to your script arguments list :

#!/bin/bash

declare -a A=("$@") [[ -p /dev/stdin ]] && {
mapfile -t -O ${#A[@]} A; set -- "${A[@]}";
}

echo "$@"

Example use :

$ ./script.sh arg1 arg2 arg3
> arg1 arg2 arg3

$ echo "piped1 piped2 piped3" | ./script.sh > piped1 piped2 piped3

$ echo "piped1 piped2 piped3" | ./script.sh arg1 arg2 arg3 > arg1 arg2 arg3 piped1 piped2 piped3

artickl
  • 71
  • 1
  • 5
7

Pipe it into xargs before the actual command, like cat text.txt | xargs ./Myscript.sh

4

If you have more than one set of arguments in the file (for multiple calls), consider using xargs or parallel, e.g.

xargs -d '\n' Myscript.sh < text.txt
parallel -j4 Myscript.sh < text.txt
reinierpost
  • 2,300
2

By reading stdin with mapfile you can re-set the positional parameters.

#!/bin/bash

[[ -p /dev/stdin ]] && { mapfile -t; set -- "${MAPFILE[@]}"; }

for i in "$@"; do echo "$((++n)) $i" done

$ cat test.txt | ./script.sh
1 first
2 second line 
3 third
0

If there are newlines (LF) or tabs in the file and you want to actually put them in one single argument (not have bash convert LF to spaces and use each word as a separate argument), you can use this:

./Myscript.sh "$(IFS=''; cat text.txt)"

(subshell used so IFS is untouched in main shell)

Simple test to show it works:

echo ">>>$(IFS=''; cat text.txt)<<<"

Non-sub-shell version:

IFS=" " ; echo ">>>$(cat text.txt)<<<" ; IFS=$' \t\n'

See also: https://stackoverflow.com/questions/2789319/file-content-into-unix-variable-with-newlines

0

This q's a bit old, but I found this solution easiest to understand and wanted to share.

If you want to accept the contents of test.txt as input to your script (e.g. cat test.txt | ./myEchoScript), you can do the following to read from stdin

if [ -p /dev/stdin ]; then
        input=$(cat)
else
        echo "expecting input to be piped in, exiting script"
        exit
fi
echo $input

Then to run:

$ echo "testing testing" > test.txt
$ cat test.txt | ./myEchoScript.sh 
testing testing
Chris
  • 101
0

Try,

 $ cat comli.txt
 date
 who
 screen
 wget

 $ cat comli.sh
 #!/bin/bash
 which $1

 $ for i in `cat comli.txt` ; do ./comli.sh $i ; done

so you can enter the values one by one to comli.sh from comli.txt.

7ochem
  • 162
Ranjithkumar T
  • 535
  • 1
  • 5
  • 6