Задать вопрос
@Kamikaze

Проблемы с mv, вызываемым из скрипта?

Есть скрипт, который передает файлы на фтп и затем перемещает их в отдельную папку
Из-за того, что имена файлов могут непредсказуемо иметь в имени пробелы и всяческие специсимволы, имя файла выводом find'а для удобства взято в одинарные кавычки
Из командной строки mv 'файл1' 'файл2' целевая_папка выполняется успешно с именами файлов, содержащим любые символы в имени, включая пробелы
Сам скрипт(точнее делающий это кусок) выглядит как-то так:
files_xml=$(find $FROM -maxdepth 1 -name "*.xml" -mmin +1 -printf "'%f' ")
if [ -n "${files_xml}" ]; then
     echo "XML Files found, transferring"
     sendToFTP "$files_xml_escaped" && mv $files_xml $SENTPATH
else
     echo "XML files not found"
fi


В итоге при выполнении его получаю груду ошибок(для каждого файла):
mv: не удалось выполнить stat для «'file.xml'»: Нет такого файла или каталога
Захожу в каталог, файл есть, stat его выполняется, вручную mv также отрабатывает.

То ли я чего-то не понимаю, то ли чертовщина-с.
  • Вопрос задан
  • 3305 просмотров
Подписаться 1 Оценить 6 комментариев
Решения вопроса 1
@ashumkin
системный разработчик
когда Вы пишете mv 'file.xml' 'new-file.xml' в командной строке Bash'а, то именно Bash "раскрывает" кавычки и запускает mv уже с параметрами в них:
mv file.xml new-file.xml

когда же Вы в скрипте вызываете
mv $file ${new_file},
где $file='file.xml' (содержит кавычки)
то mv запускается с именем файла, содержащим кавычки, а такого файла-то и нет... (собственно, об этом и сказал abcd0x00 )
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@RPG
Из вопроса не очень понял, что делает скрипт, но данный пример думаю содержит необходимое:
- find -print0 ... xargs -0 гарантирует корректность обработки спецсимволов
- отдельная функция - обрабатывать входные данные
send_and_move()
{
	stat "$@" && echo mv "$@" /tmp
}

export -f send_and_move
find -print0 | xargs -0 --no-run-if-empty bash -c 'send_and_move "$@"'
Ответ написан
Комментировать
@keich
Инженер по системам мониторинга от IBM
Если есть вероятность наличия в названиях файлов всяких спецсимволов, то стоит выполнить скрипт на perl или pyton. Ну если принципиально, то можно так(но в названии файлов не должно быть одинарных ковычек):
files_xml=$(find $FROM -maxdepth 1 -name "*.xml" -mmin +1 -printf "'%f' ")
if [ -n "${files_xml}" ]; then
echo "XML Files found, transferring"
sendToFTP "$files_xml" && echo $files_xml | sed "s/'\s'/\n/g" | tr -d "'" | xargs -I{} mv {} $SENTPATH
else
echo "XML files not found"
fi
Ответ написан
Комментировать
@abcd0x00
Вот тебе пример, как это делается обычно.

Находишь нужные файлы, а потом sed'ом составляешь команду (одну или несколько) с ними. Когда команда готова, передаёшь её по каналу на sh.
Код
[guest@localhost t]$ ll
итого 4
-rw-rw-r--. 1 guest guest    0 сен 30 13:08 a a.txt
-rw-rw-r--. 1 guest guest    0 сен 30 13:06 a.txt
-rw-rw-r--. 1 guest guest    0 сен 30 13:06 b.txt
-rw-rw-r--. 1 guest guest    0 сен 30 13:06 c.txt
drwxrwxr-x. 2 guest guest 4096 сен 30 13:19 d
[guest@localhost t]$
[guest@localhost t]$ ls
a a.txt  a.txt  b.txt  c.txt  d
[guest@localhost t]$ 
[guest@localhost t]$ files=$(find -name '*.txt')
[guest@localhost t]$ 
[guest@localhost t]$ echo "$files" | sed 's/.*/mv "&" d/'
mv "./b.txt" d
mv "./a.txt" d
mv "./c.txt" d
mv "./a a.txt" d
[guest@localhost t]$ 
[guest@localhost t]$ echo "$files" | sed 's/.*/mv "&" d/' | sh
[guest@localhost t]$ 
[guest@localhost t]$ ls
d
[guest@localhost t]$ ls d
a a.txt  a.txt  b.txt  c.txt
[guest@localhost t]$
[guest@localhost t]$ ll d
итого 0
-rw-rw-r--. 1 guest guest 0 сен 30 13:08 a a.txt
-rw-rw-r--. 1 guest guest 0 сен 30 13:06 a.txt
-rw-rw-r--. 1 guest guest 0 сен 30 13:06 b.txt
-rw-rw-r--. 1 guest guest 0 сен 30 13:06 c.txt
[guest@localhost t]$

Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы