Использование вывода ls
для получения имен файлов - плохая идея . Это может привести к сбоям и даже опасным скриптам. Это происходит потому, что имя файла может содержать любой символ, кроме /
и null
, и ls
не использует ни один из этих символов в качестве разделителя, так что если имя файла имеет пробел или новую строку, вы _получите неожиданный результат.
Есть два очень хороших способа итерации над файлами. Здесь я использовал просто echo
для демонстрации того, как что-то делать с именем файла; вы можете использовать все, что угодно.
Первый - это использование родных глобусных возможностей оболочки.
for dir in */; do
echo "$dir"
done
Оболочка расширяет */
на отдельные аргументы, которые читает цикл for
; даже если в имени файла есть пробел, новая строка или любой другой странный символ, for
будет видеть каждое полное имя как атомарную единицу; это никоим образом не анализирует список.
Если вы хотите рекурсивно перейти в подкаталоги, то этого не произойдет, если ваша оболочка не имеет некоторых расширенных глобусных возможностей (таких как bash
globstar
. Если ваша оболочка не имеет этих возможностей, или если вы хотите убедиться, что ваш скрипт будет работать на различных системах, то следующим вариантом будет использование find
.
find . -type d -exec echo '{}' \;
Здесь команда find
вызовет echo
и передаст ему аргумент с именем файла. Она делает это один раз для каждого найденного файла. Как и в предыдущем примере, нет никакого разбора списка имен файлов; вместо этого имя файла передается полностью как аргумент.
Синтаксис аргумента -exec
выглядит немного забавно. find
берет первый аргумент после -exec
и рассматривает его как выполняющуюся программу, а каждый последующий аргумент - как аргумент, передаваемый этой программе. Есть два специальных аргумента, которые -exec
должен видеть. Первый - {}
; этот аргумент заменяется именем файла, которое генерируется предыдущими частями find
. Второй - ;
, который позволяет find
знать, что это конец списка аргументов, которые нужно передать программе; find
нужен этот аргумент, потому что вы можете продолжить с большим количеством аргументов, которые предназначены для find
, а не для исполняемой программы. Причина для [ Использование вывода
lsдля получения имен файлов - плохая идея ]&003. Это может привести к сбоям и даже опасным скриптам. Это происходит потому, что имя файла может содержать любой символ, кроме
/и
null, и
ls` не использует ни один из этих символов в качестве разделителя, так что если имя файла имеет пробел или новую строку, вы _получите неожиданный результат.
Есть два очень хороших способа итерации над файлами. Здесь я использовал просто echo
для демонстрации того, как что-то делать с именем файла; вы можете использовать все, что угодно.
Первый - это использование родных глобусных возможностей оболочки.
for dir in */; do
echo "$dir"
done
Оболочка расширяет */
на отдельные аргументы, которые читает цикл for
; даже если в имени файла есть пробел, новая строка или любой другой странный символ, for
будет видеть каждое полное имя как атомарную единицу; это никоим образом не анализирует список.
Если вы хотите рекурсивно перейти в подкаталоги, то этого не произойдет, если ваша оболочка не имеет некоторых расширенных глобусных возможностей (таких как bash
globstar
. Если ваша оболочка не имеет этих возможностей, или если вы хотите убедиться, что ваш скрипт будет работать на различных системах, то следующим вариантом будет использование find
.
find . -type d -exec echo '{}' \;
Здесь команда find
вызовет echo
и передаст ему аргумент с именем файла. Она делает это один раз для каждого найденного файла. Как и в предыдущем примере, нет никакого разбора списка имен файлов; вместо этого имя файла передается полностью как аргумент.
Синтаксис аргумента -exec
выглядит немного забавно. find
берет первый аргумент после -exec
и рассматривает его как выполняющуюся программу, а каждый последующий аргумент - как аргумент, передаваемый этой программе. Есть два специальных аргумента, которые -exec
должен видеть. Первый - {}
; этот аргумент заменяется именем файла, которое генерируется предыдущими частями find
. Второй - ;
, который позволяет find
знать, что это конец списка аргументов, которые нужно передать программе; find
нужен этот аргумент, потому что вы можете продолжить с большим количеством аргументов, которые предназначены для find
, а не для исполняемой программы. Причина для в том, что оболочка также обрабатывает ;
специально - она представляет собой конец команды, так что нам нужно экранировать ее так, чтобы оболочка передавала ее в качестве аргумента find
, а не потребляла ее для себя; другой способ заставить оболочку не обрабатывать ее специально - заключить ее в кавычки: ';'
работает так же хорошо, как и \;
для этой цели.