Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash scripting redirection not working, why? [duplicate]

Tags:

bash

I found an unexpected behavior in a bash script recently and I'd like to understand it before I work around it. Here's a simplified example:

#! /bin/sh
SCRIPT="/tmp/echoscript.sh >> /tmp/log"
/bin/sh ${SCRIPT}

echoscript.sh just does 'echo "abc"'

The unexpected thing is that 'abc' goes to the terminal and not to the /tmp/log file. Why is that?

If I change the third line to:

/bin/sh ${SCRIPT} >> /tmp/log

Then I get the expected result; 'abc' goes to the log file.

like image 787
Jeff Avatar asked Dec 16 '13 22:12

Jeff


3 Answers

You can't put redirections in variables like that. When you do Bash interprets /bin/sh ${SCRIPT} as if you wrote:

/bin/sh "/tmp/echoscript.sh" ">>" "/tmp/log"

Notice how ">>" is quoted, killing the attempted redirection. This happens because Bash parses a command in phases, and parsing redirections happens before variable expansion. Variable values are not checked for redirections.

like image 160
John Kugelman Avatar answered Oct 09 '22 04:10

John Kugelman


When variables are expanded, the only further processing on the result is word splitting and wildcard expansion (aka globbing). The result is not scanned for other special operators, like redirection.

If you want full reprocessing of the command line, you have to use eval:

eval "/bin/sh ${SCRIPT}"
like image 37
Barmar Avatar answered Oct 09 '22 04:10

Barmar


This won't do what you expect since the redirect isn't being processed in ${SCRIPT}. You'll get /bin/sh: /tmp/echoscript.sh >> /tmp/log: No such file or directory.

You'll need to tell the shell to evaluate ${SCRIPT} before running it, like this:

eval /bin/sh ${SCRIPT}
$ cat /tmp/log
abc
like image 26
Donovan Avatar answered Oct 09 '22 03:10

Donovan