cwd
cwd

Reputation: 54836

basename with spaces in a bash script?

I'm working on a bash script to create a new folder in /tmp/ using the name of a file, and then copy the file inside that folder.

#!/bin/bash

MYBASENAME="`basename $1`"
mkdir "/tmp/$MYBASENAME"

for ARG in "$@"
    do
        mv "$ARG" "/tmp/$MYBASENAME"

done

Behavior:

When I type in mymove "/home/me/downloads/my new file.zip" it shows this:

mkdir /tmp/my
new
file.zip
mv: rename /home/me/downloads/my new file.zip to /tmp/my\nnew\nfile.zip:

I have lots of quotes around everything, so I don't understand why this is not working as expected.

Also, I have the form loop in there in case there are multiple files. I want them all to be copied to the same folder, based on the first argument's basename.

Upvotes: 25

Views: 27226

Answers (5)

Ziyuan
Ziyuan

Reputation: 4568

I am just copying what's from [SOLVED] mv: target `filename' is not a directory; credit to the original responder:

Add this to the start of your script. It changes the internal field separator to a newline only, and your script will treat spaces as just another character from then on.

#!/bin/bash

IFS='
'

<your script>

This Wikipedia page tells more about the special shell variable: Internal field separator.

Upvotes: 1

Jens
Jens

Reputation: 72717

In the case where the assignment is a single command substitution you do not need to quote the command substitution. The shell does not perform word splitting for variable assignments.

MYBASENAME=$(basename "$1")

is all it takes. You should get into the habit of using $() instead of backticks because $() nests more easily (it's POSIX, btw., and all modern shells support it.)

PS: You should try to not write bash scripts. Try writing shell scripts. The difference being the absence of bashisms, zshisms, etc. Just like for C, portability is a desired feature of scripts, especially if it can be attained easily. Your script does not use any bashisms, so I'd write #!/bin/sh instead. For the nit pickers: Yes, I know, old SunOS and Solaris /bin/sh do not understand $() but the /usr/xpg4/bin/sh is a POSIX shell.

Upvotes: 30

Ulrich Dangel
Ulrich Dangel

Reputation: 4625

The problem is that $1 in

MYBASENAME="`basename $1`" 

is not quoted. Use this instead:

MYBASENAME="$(basename "$1")"

Upvotes: 7

Carl Norum
Carl Norum

Reputation: 225082

You're missing one set of quotes!

MYBASENAME="`basename \"$1\"`"

That'll fix your problem.

Upvotes: 3

phoxis
phoxis

Reputation: 61950

MYBASENAME="`basename $1`"

should be

MYBASENAME="`basename "$1"`"

Wrap the $1 with double quotes "$1"

Upvotes: 0

Related Questions