184

I have a problem putting the content of pwd command into a shell variable that I'll use later.

Here is my shell code (the loop doesn't stop):

#!/bin/bash
pwd= `pwd`
until [ $pwd = "/" ]
    do
        echo $pwd
        ls && cd .. && ls 
        $pwd= `pwd` 
    done

Could you spot my mistake, please?

nbro
  • 12,226
  • 19
  • 85
  • 163
Zenet
  • 6,160
  • 13
  • 35
  • 40
  • You could also add an escape hatch to your loops in case something goes wrong. e.g. `i=0` oustide of the loop. then inside, `i=$i + 1`. And then also inside the loop, add something like `if [ $i > 25 ] then; break; endif;` I'm not sure of the loop breaking in syntax in shell scripts, but it should be something like that. – Buttle Butkus Apr 18 '13 at 03:55

5 Answers5

329

Try:

pwd=`pwd`

or

pwd=$(pwd)

Notice no spaces after the equals sign.

Also as Mr. Weiss points out; you don't assign to $pwd, you assign to pwd.

uzaif
  • 3,319
  • 2
  • 17
  • 30
John Weldon
  • 37,037
  • 10
  • 91
  • 126
  • 2
    great, thank you so much :) will definatly remember that no spaces and $ sign – Zenet Feb 22 '10 at 22:34
  • 2
    works great, but what does `$()` mean in `$(pwd)`? – AGamePlayer Sep 07 '15 at 07:04
  • 4
    @AwQiruiGuo `$()` in bash just replaces itself with the output of the command executed with the braces; so `$(pwd)` would expand to `/home/ubuntu` for example, making the assignment the equivalent of: `pwd='/home/ubuntu'` – John Weldon Oct 10 '15 at 21:47
  • @JohnWeldon `cd $pwd/newdir` does this work if the `newdir` exists? – alhelal Sep 19 '17 at 02:07
  • myPwd=$(pwd) then to output the result: $myPwd – CodeGuyRoss Nov 11 '17 at 21:27
  • 1
    @JohnWeldon It is doing more than just executing a command and assigning the results to a variable. It is creating a whole new subshell. There is a lot going on when using subshells beyond just capturing the results of a command. – Gewthen Oct 17 '20 at 17:59
34

In shell you assign to a variable without the dollar-sign:

TEST=`pwd`
echo $TEST

that's better (and can be nested) but is not as portable as the backtics:

TEST=$(pwd)
echo $TEST

Always remember: the dollar-sign is only used when reading a variable.

Johannes Weiss
  • 47,880
  • 15
  • 95
  • 129
  • 1
    Remember to use lower case for your variable names: http://stackoverflow.com/questions/673055/correct-bash-and-shell-script-variable-capitalization – Langston Jul 17 '15 at 13:13
  • And remember to [quote your variables](/questions/10067266/when-to-wrap-quotes-around-a-shell-variable/27701642). – tripleee Nov 20 '19 at 10:41
20

In this specific case, note that bash has a variable called PWD that contains the current directory: $PWD is equivalent to `pwd`. (So do other shells, this is a standard feature.) So you can write your script like this:

#!/bin/bash
until [ "$PWD" = "/" ]; do
  echo "$PWD"
  ls && cd .. && ls 
done

Note the use of double quotes around the variable references. They are necessary if the variable (here, the current directory) contains whitespace or wildcards (\[?*), because the shell splits the result of variable expansions into words and performs globbing on these words. Always double-quote variable expansions "$foo" and command substitutions "$(foo)" (unless you specifically know you have not to).

In the general case, as other answers have mentioned already:

  • You can't use whitespace around the equal sign in an assignment: var=value, not var = value
  • The $ means “take the value of this variable”, so you don't use it when assigning: var=value, not $var=value.
Gilles 'SO- stop being evil'
  • 92,660
  • 35
  • 189
  • 229
  • +1 for pointing out that `$PWD` is an internal part of bash. This gets confusing when you have a `PWD=\`pwd\`` in your script and then you `pushd` to another directory and expect `$PWD` is holding the dir before `pushd` and it doesn't! – Achilles May 11 '20 at 14:03
11

You can also do way more complex commands, just to round out the examples above. So, say I want to get the number of processes running on the system and store it in the ${NUM_PROCS} variable.

All you have to so is generate the command pipeline and stuff it's output (the process count) into the variable.

It looks something like this:

NUM_PROCS=$(ps -e | sed 1d | wc -l)

I hope that helps add some handy information to this discussion.

Jim
  • 1,157
  • 9
  • 15
  • Using an all-caps variable name is an unfortunate decision -- all-caps names are used for variables meaningful to the shell itself, whereas names with at least one lower-case character are guaranteed not to have unintended side effects in POSIX-compliant shells. For example, on ksh93, `JOBMAX` changes the number of background tasks that can be running at once; it's not hard to imagine a shell using `NUM_PROCS` for something similar. – Charles Duffy Aug 05 '18 at 18:40
1

Here's your script...

DIR=$(pwd)
echo $DIR
while [ "$DIR" != "/" ]; do
    cd ..
    DIR=$(pwd)
    echo $DIR
done

Note the spaces, use of quotes, and $ signs.

  • 1
    Remember to use lower case for your variable names: http://stackoverflow.com/questions/673055/correct-bash-and-shell-script-variable-capitalization – Langston Jul 17 '15 at 13:13
  • 1
    Also, `echo "$DIR"`, with the quotes; see [BashPitfalls #14](http://mywiki.wooledge.org/BashPitfalls#echo_.24foo). – Charles Duffy Aug 05 '18 at 18:39