238

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?

2
  • 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. Commented Apr 18, 2013 at 3:55
  • 1
    @ButtleButkus, [ $i > 25 ], is exactly the same as [ $i ] >25; that is to say, 25 is treated as a filename. You need to use -gt for numeric comparisons, or quote '>' for string comparisons. And adding one to i is i=$(( i + 1)); the syntax you have now tries to run the command + with the argument 1 and i set in its environment. And the keyword for ending an if in shell is fi. Commented Sep 19, 2022 at 19:55

5 Answers 5

408

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.

Sign up to request clarification or add additional context in comments.

7 Comments

great, thank you so much :) will definatly remember that no spaces and $ sign
works great, but what does $() mean in $(pwd)?
@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'
@JohnWeldon cd $pwd/newdir does this work if the newdir exists?
@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.
|
44

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.

2 Comments

Remember to use lower case for your variable names: stackoverflow.com/questions/673055/…
And remember to quote your variables.
22

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.

1 Comment

+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!
14

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.

1 Comment

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.
2

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.

2 Comments

Remember to use lower case for your variable names: stackoverflow.com/questions/673055/…
Also, echo "$DIR", with the quotes; see BashPitfalls #14.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.