2014-10-07 2 views
0

Я этот код, который я работал в течение нескольких часов в настоящее время, я следую его вручную, и он должен напечатать:Логическое переключатель отказывается работать должным образом

Missing Завис: notacommand

Кроме того, он отказывается работать должным образом, и я не могу понять, почему. Что я делаю не так?

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir wget notacommand) 
for d in ${__DEPENDENCIES[@]}; do 
    for i in $(echo ${PATH} | tr ":" " "); do 
    if [ -e "${i}/${d}" ] ; then 
     v=true 
     break 
    else 
     v=false 
    fi 
    done 
    if [ v = false ] ; then 
    echo "Missing dependency: ${d}" 
    exit 1 
    fi 
done 

Я извиняюсь, как я понимаю, что это плохая форма просто размещать код с просьбой о помощи, но я на самом деле не знаю, что случилось с моим кодом, в первую очередь, так что я даже не знаю, что спросить или как его спросить.

+4

[shellcheck] (http://www.shellcheck.net) любит опубликованный код и автоматически указывает на эту проблему. –

+0

О, ничего себе, это круто. Я никогда не слышал об этом сайте раньше, я обязательно начну использовать это ... – FatalKeystroke

ответ

2

Вы забываете знак доллара;)

Линия if [ v = false ] следует читать if [ $v = false ]

Хотя сценарий только дает мне «Отсутствует зависимость: pacman», когда я должен получить notacommand, а также.

+0

Вы должны шутить ... Я был в этом часами ... И сценарий предназначен для Arch Linux системы, должны были указать, я думаю. – FatalKeystroke

+1

Ах, имеет смысл. Что делать, если вы вводите 'notacommand2' в конце ваших зависимостей? Отпечатывает ли они их обоих? – Travis

+1

Печать всех отсутствующих зависимостей была в моем списке задач, но я пытался заставить ее работать в первую очередь. – FatalKeystroke

1

Тест Bash не поддерживает логическое значение, поэтому v является строковой переменной. Используйте это:

if [ "$v" = "false" ]; then 
    echo "Missing dependency: ${d}" 
    exit 1 
fi 
+0

Да. Забавные вещи могут произойти, если вы используете голые 'истинные' или' false' в скрипте, так как они являются именами команд. –

1

Хотя на ваш вопрос был дан ответ, у меня есть несколько предложений.

Вы делаете $(echo ${PATH} | tr ":" " ") внутри петли, что немного неэффективно. И на самом деле есть лучший способ разделить ваш путь. Скрипт ниже помещает элементы пути в массив. Хитрость заключается в том, чтобы временно установить внутренний разделитель поля bash на :.

Я также изменил проверку существования файла, чтобы он использовал пустую строку для false и найденную строку элемента пути для true. И я использовал современные тесты стиля [[, которые более удобны в обращении, чем старый стиль [, например, они более прощают за отсутствующие " кавычки; FWIW, сценарий ниже справляется с сумасшедшими именами файлов, которые содержат неприятные символы, такие как пробелы или кавычки. OTOH, [[ - это bash-ism, не все его оболочки поддерживают его.

#!/bin/bash 

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir zorg wget notacommand) 
IFS=':' paths=($PATH) 
# for d in "${paths[@]}"; do echo "[$d]"; done 

for d in "${__DEPENDENCIES[@]}" 
do 
    for i in "${paths[@]}" 
    do 
     v='' 
     if [[ -e $i/$d ]] 
      then v=$i; break 
     fi 
    done 

    if [[ -z $v ]] 
     then echo "Missing dependency: $d" 
     else echo "$d is in $i" 
    fi 
done 

Вот альтернативный подход, который находит только зависимость, если он фактически является исполняемым.

#!/bin/bash 

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir zorg wget notacommand) 

for f in "${__DEPENDENCIES[@]}" 
do 
    echo -n "$f : " 
    which "$f" || echo "NOT found!" 
done 
0

Вы просто переоцениваете command -v.

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir wget notacommand) 
for d in "${__DEPENDENCIES[@]}"; do 
    if ! command -v "$d" > /dev/null; then 
    echo "Missing dependency: ${d}" 
    exit 1 
    fi 
done 

Ну, возможно, нет. command все равно найдет функции оболочки, псевдонимы и т. Д., Которые вы можете игнорировать.

+0

Правда. Я предположил из кода в вопросе, что FatalKeystroke просто хочет проверить исполняемые файлы, поэтому моя альтернативная версия использует 'which'. И, конечно, это может быть просто упражнение по программированию ... –

Смежные вопросы