Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use pipes in command stored in a variable?

Tags:

bash

pipe

Trying to use pipes in bash script. This works fine on my Linux shell but bash script errors out. What am I doing wrong?

  #!/bin/bash
  #some code
  cmd="cat file2 | grep ':'  | awk -F \":\" '{print \$1}' > pool_names"
  echo $cmd
  exec $cmd
 

I see this error

cat: invalid option -- 'F'
Try 'cat --help' for more information.
like image 643
spooja__ Avatar asked Sep 21 '25 10:09

spooja__


2 Answers

In the shell, a "simple command" is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator. (See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01), while a pipeline is a sequence of one or more commands separated by the control operator '|' (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_02). When the shell sees the line exec $cmd it does not see the control operator |, so that is a simple command. (This has nothing to do with exec, and the same behavior will occur with any command.) It then expands the variables in the line and follows the rule the first field shall be considered the command name and remaining fields are the arguments for the command, so exec is called with a bunch of arguments. exec does not attempt to interpret the arguments as shell operators (perhaps you meant to use eval instead of exec), but just passes all the arguments on to cat.

like image 96
William Pursell Avatar answered Sep 23 '25 11:09

William Pursell


The bash builtin exec command has a completely different goal, as explained at https://www.computerhope.com/unix/bash/exec.htm .

You have to substitute exec with eval in order to get your script working, or as alternative, as suggested by @Jonathan Leffler in a comment, you may use bash -c "$cmd".

like image 28
Antonio Petricca Avatar answered Sep 23 '25 11:09

Antonio Petricca