Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why didn't back quotes in a shell script help me cd to a directory

Tags:

bash

shell

I have a shell script with the following code:

dir=sample
`mkdir $dir`
`cp /home/bhavya/workspace/UnetStack/logs/log-0.txt $dir/log.txt`
`cd $dir`

In the last line with the cd command in the back quotes, I was not able to cd into the corresponding directory. But once I removed the back quotes I was able to cd. What I was wondering is why didn't the cd work with the back quote?

like image 899
bhavs Avatar asked Aug 20 '12 06:08

bhavs


1 Answers

When you ran:

`mkdir $dir`

the shell first ran the command mkdir $dir in a subshell, capturing its (standard) output, and then ran the captured string as a command. Fortunately, the output was empty, so the second step executed nothing.

When you then ran:

`cp /home/bhavya/workspace/UnetStack/logs/log-0.txt $dir/log.txt`

the copy was executed in a subshell, and the output was captured and executed. Again, the output was empty, so the second phase of execution did nothing.

Then you ran:

`cd $dir`

Once more, the cd operation was run in a subshell, which exited after changing its own current working directory, but without affecting the parent shell (this is Unix, not a DOS .bat command file). As before, the output of the cd command was captured, and executed, but the output was empty so there was nothing to execute.

Essentially, you don't use back-quotes as extensively as you are doing.

It would be sufficient to write:

dir=sample
mkdir $dir
cp /home/bhavya/workspace/UnetStack/logs/log-0.txt $dir/log.txt
cd $dir
...other activity in the new directory...

Note that if this is in a script, then the normal ways of executing a script would still leave the parent shell in the original directory. There are ways to make it affect the original shell — find out about the . command (or, in bash, the source command; that's easier to search for).

You normally use back quotes (or, better, the $(...) notation) to capture data. For example:

gcc_lib_dir=$(dirname $(dirname $(which gcc)))/lib

The innermost command is which gcc; it might yield /usr/gcc/v4.7.1/bin/gcc; the inner dirname then yields /usr/gcc/v4.7.1/bin; the outer dirname yields /usr/gcc/v4.7.1; the appended /lib gives

gcc_lib_dir=/usr/gcc/v4.7.1/lib

That also shows why $(...) is superior to the back-quote notation:

gcc_lib_dir=`dirname \`dirname \\\`which gcc\\\`\``/lib

That's harder to get right, and harder to type!

like image 51
Jonathan Leffler Avatar answered Oct 20 '22 22:10

Jonathan Leffler