Ошибка при вызове mv с подстановочными знаками

Если Вы не хотите сохранить порядок элементов на уникальной строке, то можно отсортировать каждую строку, то вид строки и удаляет дубликаты.

awk '{ if ($2 < $1) print $2, $1; else print $1, $2; }' | sort -u
3
11.06.2014, 01:57
2 ответа

При вызове программы с подстановочным символом, оболочка, которую вы используете, попытается расширить этот символ и дать расширенные имена файлов в качестве аргументов исполняемому файлу. Если он не может быть расширен, оболочка выдаст процессу подстановочные знаки в виде имён файлов.

Смотрите следующий вывод strace (файлы существуют):

user@host:~$ mv test* /tmp/
execve("/bin/mv", ["mv", "test", "test1", "test2", "test3", "/tmp"], [/* 19 vars */]) = 0

Теперь этот вывод strace (файл, соответствующий подстановочному знаку, не существует).

user@host:~$ mv test* /tmp/
execve("/bin/mv", ["mv", "test*", "/tmp/"], [/* 19 vars */]) = 0

При перемещении файла с помощью mv, программа mv сначала пытается получить статус этого файла. Это было сделано с помощью системного вызова stat (см. man 2 stat). Если статус файла (или нескольких файлов в вашем случае) не может быть собран, процесс mv не может быть продолжен.

Во втором случае, системный вызов статистики не удается:

lstat("test*", 0x7fff20d26490)          = -1 ENOENT (No such file or directory)

Вырезать короткое изложение длинной истории: Нет файлов, которые соответствовали бы утверждению ACQ*.err.

.
1
27.01.2020, 21:28

Когда шаблон подстановки не совпадает ни с одним файлом, оболочка оставляет его без изменений.

Чтобы избежать поддельной ошибки, сначала пусть совпадения будут расширены, а затем проверьте, не является ли результат несуществующим файлом.¹ Параметры позиционирования (которые обычно содержат аргументы, передаваемые в скрипт) можно установить в список файлов.²

set -- Abc*.err
if [ -e "$1" ]; then
  mv "$@" /path/dir/folder/exc/a/update/Abd/ER/BkError/
fi

В bash, но не в обычном sh, можно изменить конфигурацию, чтобы расширить не совпадающие шаблоны на пустую строку вместо того, чтобы оставить их нетронутыми.

shopt -s nullglob
err_files=(Abc*.err)
if ((${#err_files[@]} != 0)); then
  mv "${err_files[@]}" /path/dir/folder/exc/a/update/Abd/ER/BkError/
fi

¹ Это может привести к ложным срабатываниям с паттернами, содержащими [...]. Для полноты следует также проверить, совпадает ли расширение с оригиналом.
² Смотрите "Как обработать список имён файлов" в Почему мой скрипт оболочки давится пробелами или другими специальными символами? для более подробных пояснений.

1
27.01.2020, 21:28

Теги

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