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


$* | someothercommand

But to no avail...


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 
  • Why not 'eval "$@"' in the script? – Jonathan Leffler Mar 3 '10 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. – Martin Hilton Mar 3 '10 at 9:17
  • @Martin Hilton, thanks for the great answer - eval was what I was missing! – bguiz Mar 3 '10 at 23:42
  • +1 @Martin Hilton for need to use quotes when pipes are involved – bguiz Mar 3 '10 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; } – Jonathan Leffler Mar 5 '10 at 0:06

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.