Невозможно скопировать массив файлов с пробелами внутри имени файла внутри скрипта bash - PullRequest
0 голосов
/ 14 октября 2018

У меня есть скрипт bash my_tar.sh, который вызывает tar czf output.tgz для 3 файлов с пробелами в именах файлов, передаваемых из массива: file, file 2 и file 3.

#!/bin/bash

declare -a files_to_zip

files_to_zip+=(\'file\')
files_to_zip+=(\'file 2\')
files_to_zip+=(\'file 3\')

echo "tar czf output.tgz "${files_to_zip[*]}""
tar czf output.tgz "${files_to_zip[*]}" || echo "ERROR"

Хотя три файласуществует, когда tar запускается внутри скрипта, он заканчивается ошибкой.Однако, когда я буквально запускаю вывод echo (который совпадает со следующей командой my_tar.sh) внутри консоли bash, tar работает нормально:

$ ls
file  file 2  file 3  my_tar.sh
$ ./my_tar.sh
tar czf output.tgz 'file' 'file 2' 'file 3'
tar: 'file' 'file 2' 'file 3': Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
ERROR
$ tar czf output.tgz 'file' 'file 2' 'file 3'
$ 

Есть идеи?

1 Ответ

0 голосов
/ 14 октября 2018

Проблема в том, что вы экранируете ' и тем самым добавляете его в имя файла вместо того, чтобы использовать его в кавычках:

files_to_zip+=(\'file 2\')

против

files_to_zip+=( 'file 2' )

Кроме того, обычно рекомендуется использовать @ вместо звездочки (*) для ссылки на все элементы массива, поскольку звездочка не будет интерпретироваться при заключении в кавычки (-> http://tldp.org/LDP/abs/html/arrays.html, Пример 27-7).

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

echo "tar czf output.tgz \"${files_to_zip[@]}\""

Ваш фиксированный скрипт будет выглядеть так:

#!/bin/bash

declare -a files_to_zip

files_to_zip+=( 'file' )
files_to_zip+=( 'file 2' )
files_to_zip+=( 'file 3' )

echo "tar czf output.tgz \"${files_to_zip[@]}\""
tar czf output.tgz "${files_to_zip[@]}" || echo "ERROR"
...