Ответ 1
Две вещи. Никогда не используйте ls
для итерации файлов и цитирования разложений параметров "$x"
. Синтаксис for и if корректен. Я предпочитаю помещать do
и then
в одну строку, хотя
for file in *; do
if [[ -d "$file" ]]; then
echo "$file is a directory"
elif [[ -f "$file" ]]; then
echo "$file is a regular file"
fi
done
Для обучения bash, я рекомендую читать http://mywiki.wooledge.org/BashGuide большинство других учебных пособий, и, к сожалению, не очень хорошие руководства.
Причиной не выполнять for x in $(ls)
для итерации файлов является то, что for
выполняет итерацию слов, а ls
выводит строки с именами файлов. если эти имена файлов содержат пробелы, эти имена файлов будут далее разделены на слова, поэтому вы будете итерировать слова имен файлов, а не имена файлов. Очевидно, что для простых случаев, которые работают, но зачем использовать полурабочее решение, когда есть более короткий и элегантный способ, который обрабатывает все случаи?
С for x in *
оболочка заменяет *
на все имена файлов, соответствующие этому шаблону в текущем каталоге (называемое расширением имени пути), и каждое имя файла будет отдельным словом, поэтому оно будет работать независимо от того, какие символы содержит имя файла. Имена файлов могут содержать любой символ (включая символы новой строки), кроме /
и NUL-байта (\ 0).
Подробнее см. http://mywiki.wooledge.org/ParsingLs.
Что касается использования [[
vs [
. [
- это команда, унаследованная от оболочки bourne, используемая для проверки строк, файлов и чисел. Bash добавил более мощное ключевое слово [[
, которое может делать все [
и может. Если вы пишете sh script, вы должны использовать [
, но в сценариях Bash вы должны использовать более мощные синтаксисы [[
и ((
. Подробнее о разнице между [
и [[
см. http://mywiki.wooledge.org/BashFAQ/031.