2015-10-31 3 views
0

Я написал сценарий оболочки для определения того, установлен ли пакет или нет. Мой скрипт должен записать свое имя и статус, если он установлен. Я не могу понять какие-либо проблемы с моим кодом, но когда я его запускаю, он не выполняет команды в соответствии с условием if [ $? == 0 ].Ошибка в сценарии оболочки для обнаружения пакетов в системе

#!/bin/bash 

if [ "$1" == "" ]; then 
    echo "Please hold the line." 
else 
    dpkg -s [email protected] &> /dev/null 
fi 

if [ $? == 1 ]; then 
    echo -e "Package \033[0;31mNOT\033[0m found." >&2 
else 
    if [ $? == 0 ]; then 
     for i in [email protected]; do 
      dpkg -s $i | grep Package 
      dpkg -s $i | grep Status 
     done 
    fi 
fi 

Но самая странная вещь для меня в том, что она работает, если я добавляю эхо после утверждения if. Похоже, что:

#!/bin/bash 

if [ "$1" == "" ]; then 
    echo "Please hold the line." 
else 
    dpkg -s [email protected] &> /dev/null 
fi 

if [ $? == 1 ]; then 
    echo -e "Package \033[0;31mNOT\033[0m found." >&2 
else 
    echo hi 
    if [ $? == 0 ]; then 
     for i in [email protected]; do 
      dpkg -s $i | grep Package 
      dpkg -s $i | grep Status 
     done 
    fi 
fi 

Так что, если я добавить echo -n в правильном положении в моем коде он будет работать, как я хочу. Но я просто хочу знать, что не так с первым?

+0

Вы пробовали 'elif'? –

+1

Сохранить $? к переменной. – Cyrus

+0

В стороне: поскольку вы используете 'bash', вам [лучше использовать' [[', а не' ['for conditionals] (http://stackoverflow.com/a/29320710/45375). Если цель состоит в том, чтобы оставаться переносной, объединение '[' с '==' не имеет смысла, потому что строго POSIX-совместимые оболочки распознают '='. Наконец, '==' (и '=') предназначены для сравнения _string_; лучше использовать '-eq' для тестирования _numeric_ equal. – mklement0

ответ

1

$? - это статус возврата последней выполненной команды. 0 успешно, 1 или что-то еще - ошибка. Примечание:

dpkg -s python &> /dev/null # returns 0 (OK, true) 
# $? equals 0 now 

[ #? == 1 ] # false   # returns 1 (error) 
# $? equals 1 now 

[ #? == 0 ] # false   # returns 1 (error) 

Когда вы положили эхо, он работает:

dpkg -s python &> /dev/null # returns 0 (OK, true) 
# $? equals 0 now 

[ #? == 1 ] # false   # returns 1 (error) 
# $? equals 1 now 

echo hi      # returns 0 (OK) 
# $? equals 0 now 

[ #? == 0 ] # true   # returns 0 (OK) 

Вы можете сохранить $? переменной, но вы действительно не нужен, если внутри else, так как вы уже проверили, если #? == 1 так просто поставить свой код в другом:

#!/bin/bash 

if [ "$1" == "" ]; then 
    echo "Please hold the line." 
else 
    dpkg -s [email protected] &> /dev/null 
fi 

if [ $? == 1 ]; then 
    echo -e "Package \033[0;31mNOT\033[0m found." >&2 
else 
    for i in [email protected]; do 
     dpkg -s $i | grep Package 
     dpkg -s $i | grep Status 
    done 
fi 

Если вы беспокоитесь о других возможных состояниях возвращаемых $? (больше одного). Вы можете переписать свой сценарий на

#!/bin/bash 

if [ "$1" == "" ]; then 
    echo "Please hold the line." 
else 
    dpkg -s [email protected] &> /dev/null 
fi 

if [ $? == 0 ]; then 
    for i in [email protected]; do 
     dpkg -s $i | grep Package 
     dpkg -s $i | grep Status 
    done 
else 
    echo -e "Package \033[0;31mNOT\033[0m found." >&2 
fi 
2

Я думаю, что в целом вы можете быть более преднамеренным в отношении обработки кода возврата. Вы делаете предположения о том, что относится к $?, это может быть недействительным в зависимости от вашего потока программы и, вне зависимости от того, сделать программу более трудной для чтения и понимания.

#!/bin/bash 

dpkg -s [email protected] &> /dev/null 
installed=$? 

if [ $installed -eq 0 ]; then 
    for i in [email protected]; do 
     dpkg -s $i | grep Package 
     dpkg -s $i | grep Status 
    done 
else 
    echo -e "Package \033[0;31mNOT\033[0m found." >&2 
fi 
+0

Красиво сделано; для поощрения хороших привычек, пожалуйста, дважды укажите экземпляры '$ @'. – mklement0

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

  • Нет связанных вопросов^_^