Basename с пробелами в bash script?

Я работаю над bash script, чтобы создать новую папку в /tmp/, используя имя файла, а затем скопируйте файл внутри этой папки.

#!/bin/bash

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

for ARG in "[email protected]"
    do
        mv "$ARG" "/tmp/$MYBASENAME"

done

Поведение:

Когда я набираю mymove "/home/me/downloads/my new file.zip", он показывает это:

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

У меня много котировок вокруг всего, поэтому я не понимаю, почему это работает не так, как ожидалось.

Кроме того, у меня есть цикл формы там, где есть несколько файлов. Я хочу, чтобы все они были скопированы в одну и ту же папку, основываясь на первом аргументе basename.

Ответы

Ответ 1

В случае, когда назначение является одной подстановкой команды, вам не нужно указывать замену команды. Оболочка не выполняет разбиение слов для присваиваний переменных.

MYBASENAME=$(basename "$1")

- это все, что требуется. Вы должны привыкнуть использовать $() вместо backticks, потому что $() легче гнездится (это поддерживает POSIX, btw. И все современные оболочки).

PS: вы должны попробовать не писать сценарии bash. Попробуйте написать сценарии shell. Разница заключается в отсутствии базизмов, zshisms и т.д. Точно так же, как и для C, переносимость является желаемой особенностью скриптов, особенно если ее можно легко достичь. Ваш script не использует никаких базизмов, поэтому я бы написал вместо #!/bin/sh. Для nit pickers: Да, я знаю, старые SunOS и Solaris /bin/sh не понимают $(), но /usr/xpg4/bin/sh - это оболочка POSIX.

Ответ 2

Проблема заключается в том, что $1 в

MYBASENAME="`basename $1`" 

не цитируется. Используйте это вместо:

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

Ответ 3

Вам не хватает одного набора кавычек!

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

Это исправит вашу проблему.

Ответ 4

MYBASENAME="`basename $1`"

должен быть

MYBASENAME="`basename "$1"`"

Оберните $1 двойными кавычками "$1"