3

I want to write a script that will repeat a commandline that usually contains pipes

./myscript.sh ls -lart |grep ^d

And in myscript.sh I do a bunch of stuff, and then want to execute ls -lart |grep ^d and pipe the output from that into something else.

(sorry in advance if this is really simple and has a 1-liner solution).

So far I have tried

$@ | someothercommand

and

$* | someothercommand

But to no avail...

1 Answer 1

8

The way the shell parses the command line means that the inputs to your shell script will stop when it gets to the pipe. What you will probably have to do to get round this is put your command line in quotes, so:

./myscript.sh "ls -lart |grep ^d"

Then in your script use the eval command to execute it, as in:

 eval "$@" | someothercommand 
6
  • Why not 'eval "$@"' in the script? Mar 3, 2010 at 7:27
  • 1
    @Jonathan Leffler because bash will will stop processing arguments for the script when it gets to the pipe. bash will execute ./myscript ls -lart and pipe whatever output it gets through grep ^d. I think the idea was to be able to use the output of ls -lart | grep ^d in the script. Although eval "$@" would work just as well. The point is that the pipe character needs to be in quotes so that it is not parsed by the shell when the command is executed. Mar 3, 2010 at 9:17
  • @Martin Hilton, thanks for the great answer - eval was what I was missing!
    – bguiz
    Mar 3, 2010 at 23:42
  • +1 @Martin Hilton for need to use quotes when pipes are involved
    – bguiz
    Mar 3, 2010 at 23:49
  • You got my up-vote anyway (y'day) for a not desperately well thought out question. What I had in mind was: myscript "ls -lart" "|grep ^d" "|sed 's/^/ /'", which has 3 arguments. It isn't very sensible; but ignoring the extra arguments on the command line isn't all that sensible. It's tricky. If there is more than one argument to 'myscript', you really should do something with or about the extras. But it is debatable whether the 3-argument command line I showed is really better than just erroring: [ $# -gt 1 ] && { echo "Usage: $0 'command | pipeline'" 1>&2; exit 1; } Mar 5, 2010 at 0:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .