Команда в переменной не запускается с пробелами в именах файлов - PullRequest
0 голосов
/ 10 декабря 2018

Мне нравится возможность в оболочке linux сохранять команды в переменную:

mycommand="cp fileOne.txt fileTwo.txt /home/myself/targetdir"
$mycommand

Это хорошо работает.

Но как обрабатывать пробелы внутри имен файлов?

Следующие альтернативы работают хорошо:

cp file\ One.txt file\ Two.txt /home/myself/targetdir
# and also
cp "file One.txt" "file Two.txt" /home/myself/targetdir

Теперь я пытаюсь поместить это и в свою переменную (для вызова $mycommand).

Но ни одна из моих следующих попыток не запускается:

mycommand="cp file\ One.txt file\ Two.txt /home/myself/targetdir"
mycommand="cp \"file One.txt\" \"file Two.txt\" /home/myself/targetdir"
mycommand="cp 'file One.txt' 'file Two.txt' /home/myself/targetdir"
mycommand='cp "file One.txt" "file Two.txt" /home/myself/targetdir'

Во всех параметрах аргументы разделяются пробелами, файл "файл" не будет найден.

Что я могу сделать вместо этого?

(яинтересно, почему я не могу найти подобный вопрос, уже принятый по этому поводу ...)

РЕДАКТИРОВАТЬ:

с set -x Я получаю следующие строки для cp, в зависимости от попытки выше:

+ cp 'file\' One.txt 'file\' Two.txt /home/myself/targetdir
+ cp '"file' 'One.txt"' '"file' 'Two.txt"' /home/myself/targetdir
+ cp ''\''file' 'One.txt'\''' ''\''file' 'Two.txt'\''' /home/myself/targetdir
+ cp '"file' 'One.txt"' '"file' 'Two.txt"' /home/myself/targetdir

Первая строка вывода для каждой попытки, переведенная с немецкого на английский, выглядит так:

cp: cannot stat 'file\': No such file or directory
cp: cannot stat '"file'’: No such file or directory
cp: cannot stat ''\''file': No such file or directory
cp: cannot stat '"file': No such file or directory

Кажется, что командная строка отделена пробелами, игнорируя "" и \ - но почему?И как мне этого избежать?

1 Ответ

0 голосов
/ 12 декабря 2018

Я нашел решение:

eval $mycommand

и, вероятно, более безопасный для других ценариев,

eval "$mycommand"

будет работать, как и ожидалось.

eval переменные будут расширены перед выполнением.)

Пример практического использования:

Имеется инструмент для объединения PDF-файлов, такой как pdfunite:

for file in *.pdf; do
    inputfiles="$inputfiles \"$file\""
done
eval "pdfunite $inputfiles mergedOutputfile.pdf"
...