Reputation: 1954
My bash script is written to go to each subfolder in the current directory:
for d in */;
do
target=${d%/}
cd "$target"
done
When I run my bash script, I am getting a cd error for a directory that exists:
++ for d in '*/'
++ target='Zelkova serrata'
++ cd 'Zelkova serrata'
./script7.sh: line 8: cd: Zelkova serrata: No such file or directory
Yet, in terminal command line I can do cd 'Zelkova serrata'
within the same directory as the script and all is fine. Is it possible the bash script has a different source directory than the one its located in?
Upvotes: 0
Views: 9823
Reputation: 697
To understand what's happening, try this and examine the output carefully:
mkdir -p A/B/C B C D
echo Trying sequence: */
pwd
for d in */ ; do
cd "$d"
pwd
done
Perhaps what you want is:
mkdir -p A/B/C B C D
exec 3<. ; orig_dir=/proc/$$/fd/3
echo Trying sequence: */
pwd
for d in */ ; do
cd -P "$orig_dir/$d"
pwd
done
cd -P "$orig_dir"
pwd
or if exec 3<.
does not work in your shell:
mkdir -p A/B/C B C D
orig_dir=$PWD
echo Trying sequence: */
pwd
for d in */ ; do
cd -P "$orig_dir/$d"
pwd
done
cd -P "$orig_dir"
pwd
Upvotes: 0
Reputation: 286
With bullet proofing
~$ find /full/path/to/dir -maxdepth 1 -type d -printo | xargs -0 -I% sh -c "cd %; echo "do some fun here""
You'll escape name splitting if there is any space there.
Upvotes: 0
Reputation: 27473
The issue is that the current directory is "state" that is modified on each pass of the loop and to use the posted commands, the cwd state should not be changed by a pass.
Spawning a subshell can fix this problem of mutating state. The subshell inherits the state of its parent, but does not affect the parent.
do ( command; command ; ...; )
will spawn a new shell on each loop pass.
for d in */;
do (
target=${d%/}
cd "$target"
) done
Upvotes: 2
Reputation: 2356
You are looping through relative paths, try including the absolute path, for example:
#!/bin/bash
pwd=$PWD
for d in */;
do
target="$pwd/${d%/}"
cd "$target"
echo $PWD
done
Upvotes: 3