124

I'm using Bash on macOS X and I'd like to create a simple executable script file that would change to another directory when it's run. However, the path to that directory has spaces in it. How the heck do you do this? This is what I have...

Name of file: cdcode

File contents:

cd ~/My Code

Now granted, this isn't a long pathname, but my actual pathname is five directories deep and four of those directories have spaces in the path.

BTW, I've tried cd "~/My Code" and cd "~/My\ Code" and neither of these worked.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
  • 1
    I am having a similar problem as the one described. I.e. none of the possible ways to change to a directory wich has a space in it. Nothing like : cd "My Passport" cd My\ Passport cd My" Passport" nothing is working. The complition works fine. I can list : ls -l My\ Passport/ works fine. \>uname -a Linux host 2.6.18-8.1.8.el5.centos.plus #1 SMP Mon Jul 16 08:49:50 EDT 2007 i686 i686 i386 GNU/Linux \>bash --help GNU bash, version 3.1.17(1)-release-(i686-redhat-linux-gnu) any ideas please? – Denis C Jan 22 '10 at 18:23

14 Answers14

102

When you double-quote a path, you're stopping the tilde expansion. So there are a few ways to do this:

cd ~/"My Code"
cd ~/'My Code'

The tilde is not quoted here, so tilde expansion will still be run.

cd "$HOME/My Code"

You can expand environment variables inside double-quoted strings; this is basically what the tilde expansion is doing

cd ~/My\ Code

You can also escape special characters (such as space) with a backslash.

derobert
  • 49,731
  • 15
  • 94
  • 124
50

I found the solution below on this page:

x="test\ me"  
eval cd $x

A combination of \ in a double-quoted text constant and an eval before cd makes it work like a charm!

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
user365757
  • 525
  • 4
  • 2
22

After struggling with the same problem, I tried two different solutions that works:

1. Use double quotes ("") with your variables.

Easiest way just double quotes your variables as pointed in previous answer:

cd "$yourPathWithBlankSpace"

2. Make use of eval.

According to this answer Unix command to escape spaces you can strip blank space then make use of eval, like this:

yourPathEscaped=$(printf %q "$yourPathWithBlankSpace")
eval cd $yourPathEscaped
Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
HanniBaL90
  • 535
  • 6
  • 18
11

You can use any of:

cd ~/"My Code"
cd ~/M"y Code"
cd ~/My" Code"

You cannot use:

cd ~"/My Code"

The first works because the shell expands ~/ into $HOME/, and then tacks on My Code without the double quotes. The second fails because there isn't a user called '"' (double quote) for ~" to map to.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
10
cd ~/My\ Code

seems to work for me... If dropping the quotes but keeping the slash doesn't work, can you post some sample code?

Andrew Flanagan
  • 4,267
  • 3
  • 25
  • 37
7

This will do it:

cd ~/My\ Code

I've had to use that to work with files stored in the iCloud Drive. You won't want to use double quotes (") as then it must be an absolute path. In other words, you can't combine double quotes with tilde (~).

By way of example I had to use this for a recent project:

cd ~/Library/Mobile\ Documents/com~apple~CloudDocs/Documents/Documents\ -\ My\ iMac/Project

I hope that helps.

Josh
  • 157
  • 1
  • 7
4

A single backslash works for me:

ry4an@ry4an-mini:~$ mkdir "My Code"

ry4an@ry4an-mini:~$ vi todir.sh

ry4an@ry4an-mini:~$ . todir.sh 

ry4an@ry4an-mini:My Code$ cat ../todir.sh 
#!/bin/sh
cd ~/My\ Code

Are you sure the problem isn't that your shell script is changing directory in its subshell, but then you're back in the main shell (and original dir) when done? I avoided that by using . to run the script in the current shell, though most folks would just use an alias for this. The spaces could be a red herring.

Ry4an Brase
  • 78,112
  • 7
  • 148
  • 169
  • Thanks, Ry4an (and the rest of the respondents). It seems that I was executing the script incorrectly. I was just trying to run it like so: % ./cdsomedir I didn't realize I needed to use the "." to run the script as you did: % . cdsomedir.sh Once I did that, it worked. Newbie mistake. Thanks! –  Mar 01 '09 at 01:00
  • The `#!/bin/sh` line does not do anything useful with a file which you need to invoke with `.` anyway. – tripleee Jan 27 '23 at 10:43
2

use double quotes

go () 
{ 
    cd "$*"
}
Bobo
  • 8,777
  • 18
  • 66
  • 85
  • Thanks. A useful addition to the functions in a `.bashrc` file for changing directory when pasting directory names containing spaces on to the command line without having to then escape the spaces or quote the whole thing. `cds` is a better name though. – mattst Nov 25 '16 at 14:36
  • Is there any way to extend this (without an if) such that just `go` will be equivalent to `cd`, i.e., cd to home directory? – zennehoy Aug 03 '17 at 16:41
2

The very simple way of doing this is-

 $ cd My\ Folder

In bash, run DIR command and in the results you would see that the folder or path names having space between them has been written in the results like this -

$dir
My\ Folder
New\ Folder
Mayukh Datta
  • 91
  • 1
  • 4
2

Use single quotes, like:

myPath=~/'my dir'

cd $myPath
AAM111
  • 1,178
  • 3
  • 19
  • 39
Jadian
  • 4,144
  • 2
  • 13
  • 10
2

When working under Linux the syntax below is right:

cd ~/My\ Code

However when you're executing your file, use the syntax below:

$ . cdcode

(just '.' and not './')

Alterlife
  • 6,557
  • 7
  • 36
  • 49
  • Out of wild curiosity, why does that matter? I've only ever seen './' useed. – whaley May 13 '10 at 12:29
  • ./ will spawn a new shell, and then change the directory. So when the script exits, it goes back to the shell which spawned the new shell... you'll be in the directory where you executed the script instead of ~/My Code. '.' on the other hand causes the script to be executed in the current instance of the shell. – Alterlife May 17 '10 at 07:49
  • The dot "." is a unix command, an alias for the "source" command. It should be followed by a filename. So "source myfile" will run the file within your current shell. And ". myfile" will do the same. The "./" variable means "current directory" and is not a command. – JPGConnolly May 20 '15 at 17:10
1

Avoid ~ in scripts; use $HOME instead.

1

I read all these, and they didn't seem to work on macOS Monterey. I then changed the header from #!/bin/sh to #!/bin/zshand that seemed to do the trick.

konsolebox
  • 72,135
  • 12
  • 99
  • 105
K John Smith
  • 179
  • 6
0

I had a similar problem now were I was using a bash script to dump some data. I ended up creating a symbolic link in the script folder with out any spaces in it. I then pointed my script to the symbolic link and that works fine.

To create your link. ln -s [TARGET DIRECTORY OR FILE] ./[SHORTCUT]

Mau or may not be of use.