2

I have found the answer to get my code to work but I want to know why it works and my code doesn't

rFunc() {
  for d in *; do
    if [ -d "$d" ]; then
      cd "$d"
      rFunc
    fi
    #Do Something
  done
}

This code will go though only one sub directory but if I use the code from this answer it goes though all sub directories. Why?

(cd -- "$d" && rFunc)

Also, what is the purpose of the --? My code works without it.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Gary
  • 318
  • 3
  • 14
  • `rm --help | grep -- -foo` should give some good info about `--` if `--help` is available in your system – Jetchisel Dec 11 '22 at 21:40
  • 1
    that other answer performs the `cd` within a subprocess with the net result being that upon exiting the subprocess the parent hasn't actually performed a `cd`; your code performs the `cd` in the current session scope but never does a `cd ..` (or `cd -`) to get back to the 'starting point' before processing the next item in the loop – markp-fuso Dec 11 '22 at 21:42
  • 2
    For the last question, see: [Where is the `--` (double dash) argument documented?](https://unix.stackexchange.com/questions/570729/where-is-the-double-dash-argument-documented) – John Kugelman Dec 11 '22 at 21:43
  • 1
    https://www.gnu.org/software/bash/manual/bash.html#Command-Grouping – Jetchisel Dec 11 '22 at 21:44
  • 2
    depending on what `#Do Something` entails you could also run into issues with the re-use of the globally scoped variable `d`, ie, each func call is processing the same single `d` variable; consider adding `local d` at the beginning of the function to insure each function invocation is working with a 'local' variable `d` – markp-fuso Dec 11 '22 at 21:49

1 Answers1

1

(cd -- "$d" && rFunc) performs the cd in subshell and the parent call's current directory is unchanged, whereas your version cd's into $d but doesn't back out of it after rFunc returns.

To fix yours you should put the subshell back in, or go back up to the parent directory explicitly, e.g. with:

cd "$d"
rFunc
cd ..

or:

pushd "$d"
rFunc
popd
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • Note: `cd -` also goes back to the previous directory, but it only works once, so it's no good here. – John Kugelman Dec 11 '22 at 21:44
  • Also, it's important to check for and handle errors when using `cd` (e.g. `cd somedir || { error handler goes here; }`) in a script, because if any `cd` command fails, the entire rest of the script may execute in ... unexpected ... places. I generally prefer to avoid `cd` in scripts, and instead use explicit paths to tell commands where to operate. – Gordon Davisson Dec 11 '22 at 23:17