Я просто пытался перечислить все каталоги и файлы в текущем каталоге, а также написать, если это файл или каталог, с помощью следующей команды:
find -exec echo `echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi` \;
Я знаю, что это глупая команда, я могу использовать другие вещи, такие как -type f
или -type d
, но я хочу узнать, почему этот кусок кода не работал так, как я ожидал. Он просто печатает каталог для всех из них. Например, пока вывод find
:
.
./dir
./dir/file
вывод моего кода:
. : directory
./dir : directory
./dir/file : directory
И вывод
echo `echo dir/file : ;if [ -f dir/file ]; then echo file; else echo directory;fi`
является
dir/file : file
Я работаю над Ubuntu 14.10
и используюfind (GNU findutils) 4.4.2
find -exec bash -c 'echo -n "{} : ";if [ -f "{}" ]; then echo file; else echo directory;fi' \;
"{}"
. Почему вы используетеecho
дважды?echo "{}" : ;if [ -f "{}" ]; then echo file; else echo directory;fi
\;Ответы:
Во-первых, ваш фрагмент выполняет команду
потому что он нуждается в своем выводе для оценки подстановки команд. Поскольку нет имени файла
{}
, это производит выводЗатем
find
выполняется команда с аргументами-exec
,echo
,{}
,:
,directory
, так что для каждого файла, он выводит имя файла , а затем пробел и: directory
.Что вы на самом деле хотите сделать, так это выполнить фрагмент оболочки
echo {} :; …
для каждого найденного файлаfind
. Этот фрагмент должен выполняться оболочкойfind
, а не запускаемой оболочкойfind
, поскольку он получает данные изfind
своей командной строки. Поэтому вам нужно дать командуfind
запустить оболочку:Это лучше, но все же не правильно. Он будет работать с некоторыми (не всеми)
find
реализациями, если имена ваших файлов не содержат специальных символов, но, поскольку вы интерполируете имя файла в сценарии оболочки, вы разрешаете именам файлов выполнять произвольные команды оболочки, например, если у вас есть файл, названный$(rm -rf /)
тогда, командаrm -rf /
будет выполнена. Чтобы передать имена файлов в сценарий, передайте их как отдельные аргументы.Также первая
echo
печатает перевод строки после двоеточия. Используйтеecho -n
(если ваша оболочка поддерживает это) илиprintf
избегайте этого.Вы можете использовать
-exec … {} +
для группировки вызовов оболочки, что быстрее.источник
Другой способ выполнения
if; then; else; fi
вместе сfind
:источник