12
#!/bin/bash

# 1st part
ret=$(ps aux | grep -v grep)    # thats OK 
echo $ret

# 2nd part
cmd="ps aux | grep -v grep"     # a problem with the pipe | 
ret=$($cmd)         
echo $ret

How can I use a command-string as I have in the 2nd part? Think the pipe is the problem. Tried to escape it but it did not help. Get some snytax error of ps.

3
  • 2
    This is caused by how the order of evaluation works, see here for example.
    – tomix86
    Commented Jan 4, 2018 at 15:20
  • See also BashFAQ #50. Commented Jan 4, 2018 at 15:43
  • (speaking of, how in the world does a FAQ we get asked every week get up to +5?!) Commented Jan 4, 2018 at 15:44

2 Answers 2

13

You need eval:

ret=$(eval "$cmd")
3
  • 4
    Note that it's rather hard to get quoting and backslashing right in nested evals; and it's extremely insecure to use eval if parts of the string come from the user.
    – choroba
    Commented Jan 4, 2018 at 15:23
  • Thank you for an actually working answer! now, if you could explain why you can't just do ret=eval $cmd
    – Al Ro
    Commented Mar 30, 2022 at 19:31
  • @AlRo, first: ret=eval $cmd runs $cmd with ret temporarily set to the string eval, and because the eval is data there instead of a command, the invocation of $cmd is subject to the bugs in BashFAQ #50. Second: if you don't quote the "$cmd", then its contents get word-split and glob-expanded before being glued back into a single string and passed to eval. The details of exactly how that corrupts your command depends on the details of the command and the files in your current working directory, but it's basically never something good. Commented Aug 31, 2023 at 15:30
7

Using eval is not recommended here. It can lead to unexpected results, especially when variables can be read from untrusted sources (See BashFAQ/048 - Eval command and security issues.

You can solve this in a simple way by defining and calling a function as below

ps_cmd() {
    ps aux | grep -v grep
}

and use it in the script as

output="$(ps_cmd)"
echo "$output"

Also a good read would be to see why storing commands in a variable is not a good idea and has a lot of potential pitfalls - BashFAQ/050 - I'm trying to put a command in a variable, but the complex cases always fail!

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