0

I'm trying to write a bash script that is jumping into each subfolder and then jumps back to main folder (and so on...). The difficulty are the path names that have spaces.

 for path in "`find -type d | tr -d './'`"
 do 
    echo "Next Pathname: $path"        
    cd $path   
    echo "I'm in path $pathr"
 cd ..
 done

The Error Message is "filename or path not found". When I change

 cd $path 

to

 "cd $path" 

then I get the error message "filename too long".

Could you help me? - I don't know how to separate this string (or write something more convenient).

Peter
  • 1,224
  • 3
  • 16
  • 28
  • 5
    It's `cd "$path"`. And once you start `cd`ing into nested directories your `cd ..` won't take you back. Consider using `pushd` and `popd`. And there are some other minor issues in your script, you might want to try out http://www.shellcheck.net – Biffen Feb 02 '15 at 19:54
  • Oh, and don't iterate `find` results like that, see [this answer](http://stackoverflow.com/a/7039579/418066). (And the `tr` bit looks unnecessary.) – Biffen Feb 02 '15 at 20:06
  • I never head of pushd and popd. The problem are the spaces in pathname.... When the pathname is Documents 2010 then `cd $path` will try to jump into "Documents" and not into "Documents 2010". – Peter Feb 02 '15 at 21:02
  • 1
    What Biffen is saying is that you need quotes around $path, i.e. `cd "$path"`. Then the spaces will be considered part of the whole folder name. – Ivan X Feb 02 '15 at 21:54

1 Answers1

2

The problem is that find can only output a stream of bytes, so you have to be careful to make it output something you can split in a lossless way. The only character not allowed in a file path is ASCII NUL, so let's use that:

while IFS= read -r -d '' path
do
  ( # <-- subshell avoids having to "cd back" afterwards
    if cd "$path"
    then
      echo "I'm in $path"
    else
      echo "$path is inaccessible"
    fi
  )
done <  <(find . -type d -print0)

It handles all kinds of filenames:

$ mkdir "dir with spaces" "dir with *" $'dir with line\nfeed'

$ ls -l
total 12
drwxr-x--- 2 me me 4096 Feb  2 13:59 dir with *
drwxr-x--- 2 me me 4096 Feb  2 13:59 dir with line?feed
drwxr-x--- 2 me me 4096 Feb  2 13:59 dir with spaces
-rw-r----- 1 me me  221 Feb  2 13:59 script

$ bash script
I'm in .
I'm in ./dir with spaces
I'm in ./dir with *
I'm in ./dir with line
feed
that other guy
  • 116,971
  • 11
  • 170
  • 194