cd(1) and variables with spaces (cygwin) - bash

I've been having quite an unusual problem. In my .bashrc file, I have set a variable to a path name with spaces in it. I had a feeling this would cause problems, but I played around with setting an alias in a similar way and got it to work like so:
alias npp="\"/cygdrive/c/Program Files (x86)/Notepad++/notepad++.exe\""
Now, I thought I could use the same trick for my environment variable -
export PRO="\"/cygdrive/c/Program Files (x86)\""
This worked. Kind of.
[myName]
$ echo $PRO
"/cygdrive/c/Program Files (x86)"
[myName]
$ cd $PRO
bash: cd: "/cygdrive/c/Program: No such file or directory
I've tried placing an escape before the space with and without removing the double quotes, I've tried single quotes with and without the escape. I've tried using grave accents as quotes. I've tried just the escape, I've tried
export PRO=/cygdrive/c/Program\\\ Files\\\ \\\(x86\\\)
None of this has worked. The only thing that has was -
export PRO="/cygdrive/c/Program Files (x86)"
$ cd "$PRO"
Ultimately, I'm trying to find a way to make my variable work without placing quotes around it every single time I type the variable. Having run out of ideas entirely I came here hoping for someone to be able to help me.

I got around this with wildcards:
export PRO="/cygdrive/d/Program*Files/"

Due to Word Splitting if you do not quote $PRO that white space breaks your path into multiple words.

There's no way to use a variable without quoting it in your case.

Technically, I cannot answer your question, but a good workaround is to create a link to the folder you want, create a variable for the link, and then cd to that variable. It's an annoying second step and a pointless link but if its worth putting in your bash profile it might be worth the extra hassel.
Here's what I did:
ln -sf '/cygdrive/c/Users/Mic/Desktop/PENDING - Pics/' '/cygdrive/c/Users/Mic/mypics'
Then I put this in my bash_profile and now I can cd to $pic
pic=/cygdrive/c/Users/Eric/mypics/

Just enclose the program file in double quotes in this way
/cygdrive/c/"Program Files (x86)"
It works for me

I ran into a similar issue with a shell script evaluating a directory path in a variable without escaping the space in "Program Files". I got around this by running Cygwin as an administrator and creating a symlink. None of the answers here worked.
ln -s "/cygdrive/c/Program Files" /cygdrive/c/ProgramFiles

Related

Bash:script cannot be called after adding the path

I am writing my own unix scripts so I want to add a new directory for Bash. I add sth in .bash_profile like this.
PATH="~/Documents:${PATH}"
export PATH
and in my ~/Documents, there is a file named test of which the content is
#!/usr/bin/env python3.5
print("hahahhah")
I also used
chmod 755 test
to make it executable.
But I cannot call it in terminal directly. ./test works as usual.
What went wrong?
After I change to
PATH="$HOME/Documents:${PATH}"
export PATH
nothing happens.
FDSM_lhn#9-53:~/Documents$ test
FDSM_lhn#9-53:~/Documents$ ./test
hahahhah
Solution:
The fundamental reason is that I have a command of the same name as default one, So it won't work any way! Changing name will be sufficient!
Tilde doesn't get expanded inside strings. So by quoting the right-hand side of the assignment you prevent it from being expanded and get a literal ~ in your PATH variable which doesn't help you any.
You have two ways to fix this:
Drop the quotes on the assignment (yes this is safe, even for $PATH values with spaces, etc.).
Use $HOME instead of ~.
I prefer the second solution but the first is entirely valid for this case.
Beware though that in places where you aren't doing a straight assignment you often cannot just drop the quotes and trying to use ~ will cause problems.
In which case you will end up finding a question like this with an answer like this and something ugly like this.

Is it feasible to store a string which includes a space to the variable in bash?

I want to put my ~/Library/Application Support/ directory to a variable in my ~/.bash_profile` to make it easier to reference from within Terminal. I first attempted to define it as follows:
export L=~/Library/Application\ Support
However, when I tried to source ~/.bash_profile and then called ls $L, I got an error: /Users/username/Library/Application: Not a directory.
However, no matter how I define it I cannot define it properly, as far as I came up with the way to define it. Here's the list that I tried, but none of them worked properly.
~/Library/Application Support
"~/Library/Application Support"
"~/Library/Application\ Support"
So is it feasible to store a string which includes a whitespace to a variable in bash to begin with?
Your export statement is fine; the space is properly escaped. You just need to quote the expansion of the parameter, so that bash gives a single argument to the ls command:
ls "$L"

How do I use a variable containing a filename with spaces in a bash script?

I have a simple bash script running on OS X that removes specific files and directories and copies new ones in their place. One Mac .app directory contains a space, and when I run the script there is a "No such file or directory" error.
Here is the relevant code. A good amount has been cut out, so simply hard coding these differently isn't possible (the variables must be broken up as they are):
CP="cp -Rf"
INSTALL_DIR="/Applications/"
APP="The App.app"
NEWAPP="$HOME/Downloads/The App.app"
$CP "$NEWAPP " "$INSTALL_DIR$NEWAPP"
I've tried escaping The\ App.app with no luck, as well as trying single quoting, double quoting, and double escaping, but nothing has worked. I imagine there is a simple way to do this.
Thanks for your help.
You have an extra space there, it's simply
"$NEWAPP"
enclose the whole final line in quotes:
"$CP $NEWAPP $INSTALL_DIR$NEWAPP"
it's unnecessary to keep opening and closing the quotes here, and the $CP must be contained in quotes as CP has a space in it.

CMD: Check for quotes

Let's say, the user drag and drops an file into my batch file, which causes that the batch file copies the file to a certain directory. the problem is the following command:
copy "%1" "C:\path\to\it"
The problem here is the quotes around%1. When you drag and drop something in a batch file, normally, it wouldn't put quotes, so everything's fine. But when i convert my batch file to EXE, it actually puts quotes there.
So, what i want to do is, checking if the file does have quotes, if not, than do the command above, otherwise, do the command without quotes.
Thanks.
Would the following work?
copy %1 "C:\Dir1\Dir2"
my few attempts to find a problem not quoting %1 have not resulted in adverse effects.
Not sure if the answer given here was what you were seeking, and I may be a couple of years late, but I would like to offer an alternate solution to your quoting problem as I have run into it something similar myself. Maybe it will benefit someone else.
You ARE able to strip the quotes from around variables, including the ones that are dragged and dropped. Here's how:
add a tilde to the %n variable (e.g., copy %~1 "C:\path\to\it")
For other variables within the batch file, use a similar technique, this time performing a substitution of the double-quote for nothing :"=, as in:
set filename="C:\path\to\it"
echo %filename% (will give you "C:\path\to\it")
set noquotefilename=%filename:"=%
echo %noquotefilename% (will give you C:\path\to\it without the quotes)
It is not my original solution, but I found it near the bottom of the following post:
Removing double quotes from variables in batch file creates problems with CMD environment
The substitution technique has other applications, as you could easily substitute any character for any other (e.g., :\=_ to substitute a back-slash for an underscore).
Hope this helps!
The problem is the process by which you are converting to EXE. Try a different BAT to EXE converter.

Bash script to cd to directory with spaces in pathname

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.
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.
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!
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
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.
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?
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.
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.
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 './')
use double quotes
go ()
{
cd "$*"
}
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
Use single quotes, like:
myPath=~/'my dir'
cd $myPath
Avoid ~ in scripts; use $HOME instead.
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.
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.

Resources