How to save a command in a variable in a shell script?

I would like to save the command for use in a later period in a variable (not the output of the command, but the command itself)

I have a simple script as follows:

command="ls"; echo "Command: $command"; #Output is: Command: ls b=`$command`; echo $b; #Output is: public_html REV test... (command worked successfully) 

However, when I try to do something more complex, it fails. For example, if I do

 command="ls | grep -c '^'"; 

Output:

 Command: ls | grep -c '^' ls: cannot access |: No such file or directory ls: cannot access grep: No such file or directory ls: cannot access '^': No such file or directory 

Any idea how I could store such a command (using pipes / multiple commands) in a variable for later use?

+95
variables linux bash command
Apr 11 2018-11-11T00:
source share
5 answers

Use eval:

 x="ls | wc" eval "$x" y=$(eval "$x") echo "$y" 
+131
Apr 11 2018-11-11T00:
source share

Do not use eval ! This has a great risk of introducing arbitrary code execution.

BashFAQ-50 - I'm trying to put a command in a variable, but complex cases always fail.

Put it in an array and expand all the words with double quotes "${arr[@]}" to prevent IFS from splitting words due to splitting the Word .

 cmdArgs=() cmdArgs=('date' '+%H:%M:%S') 

and look at the contents of the array inside. declare -p allows you to see the contents of an array inside with each command parameter in separate indexes. If one such argument contains spaces, quotation marks when added to an array will prevent it from breaking due to word breaking.

 declare -p cmdArgs declare -a cmdArgs='([0]="date" [1]="+%H:%M:%S")' 

and execute commands like

 "${cmdArgs[@]}" 23:15:18 

(or) generally use the bash function to run the command,

 cmd() { date '+%H:%M:%S' } 

and call the function just

 cmd 

POSIX sh has no arrays, so the closest thing you can get is to create a list of elements in positional parameters. Here is the POSIX sh way to run the mailer

 # POSIX sh # Usage: sendto subject address [address ...] sendto() { subject=$1 shift first=1 for addr; do if [ "$first" = 1 ]; then set --; first=0; fi set -- "$@" --recipient="$addr" done if [ "$first" = 1 ]; then echo "usage: sendto subject address [address ...]" return 1 fi MailTool --subject="$subject" "$@" } 

Note that this approach can only handle simple commands without redirects. It cannot handle redirects, pipelines, for / while loops, if statements, etc.

+33
May 18 '17 at 19:00
source share
 var=$(echo "asdf") echo $var # => asdf 

Using this method, the command is immediately evaluated and its return value is saved.

 stored_date=$(date) echo $stored_date # => Thu Jan 15 10:57:16 EST 2015 # (wait a few seconds) echo $stored_date # => Thu Jan 15 10:57:16 EST 2015 

Same with stick

 stored_date='date' echo $stored_date # => Thu Jan 15 11:02:19 EST 2015 # (wait a few seconds) echo $stored_date # => Thu Jan 15 11:02:19 EST 2015 

Using eval in $(...) will not make it computed later

 stored_date=$(eval "date") echo $stored_date # => Thu Jan 15 11:05:30 EST 2015 # (wait a few seconds) echo $stored_date # => Thu Jan 15 11:05:30 EST 2015 

Using eval, it is evaluated when using eval

 stored_date="date" # < storing the command itself echo $(eval "$stored_date") # => Thu Jan 15 11:07:05 EST 2015 # (wait a few seconds) echo $(eval "$stored_date") # => Thu Jan 15 11:07:16 EST 2015 # ^^ Time changed 

In the above example, if you need to run a command with arguments, put them on the line you are storing

 stored_date="date -u" # ... 

For bash scripts, this is rarely relevant, but one final note. Be careful with eval . Eval is just the lines that you control, but not lines received from an untrusted user or created from untrusted user input.

  • Thanks @CharlesDuffy for the reminder to quote the team!
+23
Nov 17 '14 at 17:33
source share

For bash, save your command as follows:

 command="ls | grep -c '^'" 

Run your command as follows:

 echo $command | bash 
0
Sep 19 '19 at 5:57
source share

No need to store commands in variables, even if you need to use them later. just follow it as usual. If you are storing a variable, you will need some kind of eval statement or call an unnecessary shell process to “execute your variable”.

-8
Apr 11 2018-11-11T00:
source share



All Articles