Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shell Script and spaces in path

Tags:

shell

I have larger shell script which handles different things.

It will get it's own location by the following...

BASEDIR=`dirname $0`/..
BASEDIR=`(cd "$BASEDIR"; pwd)`

then BASEDIR will be used create other variables like

REPO="$BASEDIR"/repo

But the problem is that this shell script does not work if the path contains spaces where it is currently executed.

So the question is: Does exist a good solution to solve that problem ?

like image 326
khmarbaise Avatar asked Dec 28 '11 16:12

khmarbaise


People also ask

Can I have spaces in file path?

Spaces are allowed in long filenames or paths, which can be up to 255 characters with NTFS. All operations at the command prompt involving long names with spaces, however, must be treated differently. Normally, it is an MS-DOS convention to use a space after a word to specify a parameter.

Do spaces matter in shell script?

For most considerations, spacing and indentation does not matter within the script (of course, we will mention some exceptions below; for example, when setting a variable one needs spaces around the assignment operator = ).

Can Linux paths have spaces?

In the Linux operating system, we can run commands by passing multiple arguments. A space separates each argument. So, if we give the path that has a space, it will be considered two different arguments instead of one a single path.


4 Answers

Be sure to double-quote anything that may contain spaces:

BASEDIR="`dirname $0`"
BASEDIR="`(cd \"$BASEDIR\"; pwd)`"
like image 129
Fred Foo Avatar answered Sep 20 '22 10:09

Fred Foo


The answer is "Quotes everywhere."

If the path you pass in has a space in it then dirname $0 will fail.

$ cat quote-test.sh
#!/bin/sh

test_dirname_noquote () {
        printf 'no quotes: '
        dirname $1
}
test_dirname_quote () {
        printf 'quotes: '
        dirname "$1"
}

test_dirname_noquote '/path/to/file with spaces/in.it'
test_dirname_quote '/path/to/file with spaces/in.it'

$ sh quote-test.sh
no quotes: usage: dirname string
quotes: /path/to/file with spaces

Also, try this fun example

#!/bin/sh

mkdir -p /tmp/foo/bar/baz
cd /tmp/foo
ln -s bar quux
cd quux
cat >>find-me.sh<<"."
#!/bin/sh

self_dir="$(dirname $0)"
base_dir="$( (cd "$self_dir/.." ; pwd -P) )"
repo="$base_dir/repo"

printf 'self: %s\n' "$self_dir"
printf 'base: %s\n' "$base_dir"
printf 'repo: %s\n' "$repo"
.

sh find-me.sh

rm -rf /tmp/foo

Result when you run it:

$ sh example.sh
self: .
base: /tmp/foo
repo: /tmp/foo/repo
like image 31
sorpigal Avatar answered Sep 23 '22 10:09

sorpigal


Quote your full variable like this:

REPO="$BASEDIR/repo"
like image 43
sralmai Avatar answered Sep 19 '22 10:09

sralmai


There is no reliable and/or portable way to do this correctly.

See How do I determine the location of my script? as to why

The best answer is the following, which is still OS dependent

BASEDIR=$(readlink -f $0)

Then you can do things like REPO="$BASEDIR"/repo , just be sure to quote your variables as you did.

like image 36
SiegeX Avatar answered Sep 21 '22 10:09

SiegeX