Сначала сделаю тестовую базу - 5 файлов и одна папка:
touch file1 file2 file3 file4 file5
mkdir folder
Затем я выполню тестовую команду. Параметр -v
указывает, что я хочу, чтобы каждая команда, выполняемая оболочкой, выводилась на stderr
. Параметр -x
указывает, что я хочу, чтобы то же самое было напечатано на stderr
- , но Я хочу, чтобы это было после оценка команды, но до оболочка запускает его.
sh -cxv 'echo mv *'
echo mv *
+ echo mv file1 file2 file3 file4 file5 folder
mv file1 file2 file3 file4 file5 folder
Итак, вы видите, что команда, которую я передаю оболочке, - это echo mv *
, а команда, выполняемая оболочкой после раскрытия *
, - echo mv
, за которым следуют все эти файлы и папка.
По умолчанию оболочка расширяет глобусы , например:
sh -cxv 'echo file[1-5]'
echo file[1-5]
+ echo file1 file2 file3 file4 file5
file1 file2 file3 file4 file5
Это результат функции set [+ -] f
glob:
sh -cxvf 'echo file[1-5]'
echo file[1-5]
+ echo 'file[1-5]'
file[1-5]
Таким образом, когда вы запускаете команду в оболочке, настроенной с параметрами по умолчанию, такими как mv *
, оболочка раскрывается в слово *
, список аргументов всех файлов в текущем каталоге, отсортированных в соответствии с к языку. Он выполняет системный вызов exec (ve)
для mv
(по сути) с добавленным списком аргументов. Итак, mv
получает все аргументы, когда оболочка их объединяет и сортирует. Помимо выполнения strace
, чтобы увидеть эти эффекты, вы можете снова использовать отладку, например:
sh -s -- mv * <<\SCRIPT
sed -n l /proc/$$/cmdline
echo "$@"
SCRIPT
sh\000-s\000--\000mv\000file1\000file2\000file3\000file4\000file5\000folder\
\000$
mv file1 file2 file3 file4 file5 folder
И переносимо:
( PS4= IFS=/; set -x mv *; : "/$*/" ) 2>&1
: /mv/file1/file2/file3/file4/file5/folder/
В основном оболочка выполняет mv
с содержимым каталога (если он не пуст и не включает файлы / папки с именами, начинающимися с .
) в качестве списка аргументов. mv
- это POSIX, указанный для интерпретации его последнего аргумента как каталога, если он вызывается с более чем двумя аргументами - точно так же ln
равно (потому что на самом деле они Невероятно похожие инструменты в базовых функциях) .
Достаточно echo
es:
sh -cxv 'mv *' ; ls
mv *
+ mv file1 file2 file3 file4 file5 folder
folder/
Все файлы были перемещены в последний аргумент - потому что это папка. Что, если это не папка?
sh -cxv 'cd *; mv *'; ls . *
cd *; mv *
+ cd folder
+ mv file1 file2 file3 file4 file5
mv: target ‘file5’ is not a directory
.:
folder/
folder:
file1 file2 file3 file4 file5
Вот как POSIX указывает, что mv
должен вести себя в этом случае:
mv [-if] source_file target_file
mv [-if] source_file... target_dir
В первой форме синопсиса
Утилита mv
должна переместить файл, названный операндом source_file, в место назначения, указанное в target_file . Эта первая форма синопсиса предполагается, когда последний операнд не называет существующий каталог и не является символической ссылкой, относящейся к существующему каталогу. В этом случае, если исходный_файл именует файл, не являющийся каталогом, а целевой_файл заканчивается завершающим символом/ косой чертой
,mv
обрабатывает это как ошибка, и операнды исходный_файл обрабатываться не будут.Во второй форме синопсиса
mv
должен переместить каждый файл, названный операндом source_file, в целевой файл в существующем каталоге, названном операндом target_dir , или на который будет ссылка, если target_dir - это символическая ссылка, указывающая на существующий каталог. Путь назначения для каждого исходного_файла должен быть конкатенацией целевого каталога, одним символом/ косой чертой
, если цель не оканчивается на/ косую черту
, и последним компонентом имени пути в исходный_файл . Эта вторая форма предполагается, когда последний операнд называет существующий каталог.
Итак, если *
расширяется до:
два файла
переименованным
во второй после того, как второй - ] отключен
. один или несколько файлов, за которыми последним следует каталог или ссылка на один
что-нибудь еще
У меня было несколько серверов, которые показали такое же поведение, сетевые / локальные преобразователи не запускались при доступе к монтированию NFS. Решением было изменение запуска службы. Не уверен насчет freebsd, но это должно дать вам отправную точку.
Вы можете проверить сообщения ядра. В CentOS или Redhat эти журналы находятся в / var / log / dmesg.
Может случиться, что во время загрузки, до того, как сетевые службы будут запущены, сервер пытается загрузить хранилище NFS и не может определить удаленный хост.
Вы также можете проверить, изменив наконец время запуска службы NFS.
Вы можете попробовать посмотреть в /var/log/boot.msg
и boot.msg
,
они содержат текст, который вы видите на экране во время загрузки.
Я предполагаю, что это может быть связано с уровнем выполнения 3 против уровня выполнения 5,
и что вы, возможно, пытаетесь смонтировать по nfs что-то, указанное в файле /etc/fstab
, до того, как все остальные необходимые службы были запущены.
Вместо использования имени хоста venture в /etc/fstab
вы можете попробовать использовать его ip-адрес. Это позволит быстро проверить, что это проблема с именем хоста или поиском dns. Возможно, вы сможете решить эту проблему, добавив venture и его ip-адрес в /etc/hosts, но это сработает, только если вы знаете, что venture не получит свой ip-адрес по dhcp.
Сеть иногда работает не полностью (, например. DNS )перед попыткой монтирования. Вы можете добавить параметры в /etc/fstab
, чтобы смягчить это. Один из них или оба могут работать на вас (Я использую оба):
venture:/usr/redacted /usr/local/redacted nfs rw,late,bg 0 0
Это late
вариант (попробовать позже в последовательности загрузки, а не раньше )иbg
(продолжать попытки в фоновом режиме ).