8

I a bash script I have the following

CMD="{ head -n1 $DATE.$FROMSTRAT.new && egrep -i \"$SYMS\" $DATE.$FROMSTRAT.new; } > $DATE.$TOSTRAT.new" 
echo "Running $CMD"                                                                                     
`$CMD`                                                                                                  

When I call the script

Running { head -n1 inputFile.new && egrep -i "X|Y" inputFile.new; } > outputFile.new
script.sh: line 17: {: command not found 

But when I run { head -n1 inputFile.new && egrep -i "X|Y" inputFile.new; } > outputFile.new on the command line it works fine.

I try to escape the { with no success, how can I do this ?

2
  • If it's a string, you will need to evaluate it with eval or by passing it to bash -c "...". But in general that is not a good idea, error-prone, accidently clobbering files with weird input, debugging etc. Why the indirection? Commented Sep 14, 2016 at 9:58
  • Consider whether your script is complicated enough that you would be better off rewriting the entire thing in a better programming language (the obvious choices are Perl and Python). Commented Sep 14, 2016 at 17:00

2 Answers 2

8

Well, if you use a variable on the command line like that, it will be split to words, but that happens after syntactical items like { (or if) are parsed. So, if you want that, you'll have to use eval

CMD="{ echo blah ; echo bleh; } > output"
eval "$CMD"
# output contains "blah" and "bleh"

Though note eval will run everything in the variable in the current shell, including assignments to variables (changing IFS may have funny effects for the rest of the script, say). You could run it in a separate shell with bash -c "$CMD" to mitigate at least the variable assignment issue.

Also note that the backticks are used to capture the output of a command, and use it on the command line, so this would run the output of $CMD also as a command:

$ CMD="echo foo"
$ `$CMD`
-bash: foo: command not found

If you're redirecting the output to a file, it won't matter, but you most likely also don't need it.

3

try

function exec_cmd() {
    printf "+ %s \n\n" "$1"
    bash -c "$1" || exit 1
}

exec_cmd '{ head -n1 inputFile.new && egrep -i "X|Y" inputFile.new; } > outputFile.new' 

Then you don't have to worry about escaping the strings.
Note about bash -c <command> usage, the next argument after <command> is used as $0 (the script's "name" from inside the script), and subsequent arguments become the positional parameters ($1, $2, etc.).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.