7

For executing command that is stored in variable the eval command is used:

└──> a="echo -e 'a\nb' | wc -l"
└──> eval $a
2

But how can it be combined with timeout command? I've tried following which gives me wrong output:

└──> timeout 10 $a
'a
b' | wc -l

And the following which gives me errors:

└──> timeout 10 "$a"
timeout: failed to run command `echo -e \'a\\nb\' | wc -l': No such file or directory

└──> timeout 10 $(eval $a)
timeout: failed to run command `2': No such file or directory

└──> timeout 10 $(eval "$a")
timeout: failed to run command `2': No such file or directory

The question can also stand: How can I be sure that following command is executed properly?

timeout 10 "$PROGRAM" "$OPT1" "$OPT2" ...
Wakan Tanka
  • 7,542
  • 16
  • 69
  • 122
  • 1
    Don't store commands in variables. Use [functions](http://tldp.org/LDP/abs/html/functions.html) instead. You can re-declare function, just as you can re-assign variables. – anishsane May 12 '15 at 10:59
  • & To answer your question, you can run `eval "timeout 10 $a"`. But always remember that [`eval` is evil](http://mywiki.wooledge.org/BashFAQ/048) & use of `eval` is [always discouraged](http://stackoverflow.com/questions/17529220/why-should-eval-be-avoided-in-bash-and-what-should-i-use-instead), unless there is absolutely no other way. – anishsane May 12 '15 at 11:01
  • Do I even need `eval` when my `PROGRAM="echo"` `OPT1="Hello"`? I thing the `eval` is useful when there are pipes (as mentioned in original question) or some other awkward characters. – Wakan Tanka May 12 '15 at 11:33
  • 1
    @anishane why is `eval` evil? your argument is similar to saying: `ls` is evil because `for i in $(ls)` is bad. Only bad usages of `eval` are bad. Now, I agree that here, OP is using an antipattern (code is not data in shell); but in the absolute, `eval` is no more evil than other commands. Also, there are very good usages of `eval`, and I don't see why its use should be discouraged. Bad usages should be discouraged, but that's a tautology. – gniourf_gniourf Feb 11 '16 at 12:50

4 Answers4

4

Simple:

a="echo -e 'a\nb' | wc -l"
eval timeout 10 $a

Output:

2
agc
  • 7,973
  • 2
  • 29
  • 50
  • add an explanation to improve answer quality – Denis Tsoi Feb 11 '19 at 04:10
  • @DenisTsoi, Explanations can be helpful, but here I dunno... what is it about this short answer that needs explaining? It's just two commands, a parameter, and the OP's `$a` string. – agc Feb 11 '19 at 20:14
  • 1
    Note that if the command includes bash internals, such as just declaring variables, this `eval timeout` will fail, because timeout can't process those commands, it just calls an external command in a subshell. – GolDDranks Mar 02 '22 at 09:09
1

This will work

if timeout "$PROGRAM" "$OPT1" "$OPT2" ... ; then
    echo Program ran successfully
else
    echo Program terminated due to timeout
fi
RTLinuxSW
  • 822
  • 5
  • 9
0

If it's about keeping commands in variables, this will work, although don't know if it's a 'proper bash way' to do it:

command.sh:

#!/bin/bash
echo -e 'a\nb' | wc -l

run.sh:

#!/bin/bash
a="command.sh"
timeout 10 ./$a
adamsko
  • 324
  • 4
  • 7
0

echo "$(timeout 10 echo -e 'a\nb' | wc -l)"
OR
echo "$(timeout 2 echo "$(eval $a)")"

explanation 1 here : HERE

explanation 2 here : HERE

Community
  • 1
  • 1
diveinsky
  • 165
  • 2
  • 8