Вложение, если в цикле - программирование

Вложение, если в цикле

Я новичок в скриптах bash, так что это, вероятно, глупая синтаксическая ошибка, но почему этот код не работает?

for x in $(ls)
do
  if [ -d $x ]
  then
  echo $x
  fi
done

Отдельные разделы for и if работают нормально сами по себе, но это не приводит к выводу.

4b9b3361

Ответ 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.

Ответ 2

Может быть, проблема с символами, используемыми для разделения разных частей инструкции?

Что делать, если вы попытались:

for x in $(ls); do if [ -d $x ]; then echo $x; fi; done

Делает ли это вывод?

Ответ 3

1) синтаксис совершенно легальный

2) Да, вы можете вложить блоки "if/else" внутри цикла. Вы также можете вставлять внутренние петли во внешний цикл:)

3) "если [-d $x]" проверяет, является ли "x" "каталогом".

Если вы не видите какой-либо вывод, возможно, у вас нет подкаталогов?

SUGGESTION:

  • открыть окно терминала

  • Запустите script. Посмотрите, получаете ли вы какой-либо результат.

  • Если нет, введите mkdir moose. Это создаст подкаталог, называемый (uncoincident) "лося".

  • Перезапустите script. Вы должны увидеть хотя бы "лося".

Ответ 4

#!/bin/bash

name=c
for command in "cd $home" " cd XSStrike" "python xsstrike.py"
do
    if [[ $name == "c" ]]; 
    then
        echo "<==========> access granted <==========>"
        $command
    else
        echo "<==========> access denied <==========>"
    fi
done