Bash - тревожный результат с IF [..] || [..] - PullRequest
1 голос
/ 26 февраля 2012

Я могу понять, почему это не работает:

#!/bin/bash

if [ $# -ne 1 ] || [ $# -ne 2 ]; then 
# Should run if there are either 1 or 2 options specified
  echo "usage: ${0##*/} <username>"
  exit
fi

При тестировании, чтобы увидеть, работает ли оно:

root@ubuntu:~# testing.sh optionone optiontwo
...Correct output...
root@ubuntu:~# testing.sh optionone
usage: testing.sh <username>

Ответы [ 3 ]

5 голосов
/ 26 февраля 2012

Изменить логическую логику:

if [ $# -ne 1 ] && [ $# -ne 2 ]; then

Или

if ! ( [ $# -eq 1 ] || [ $# -eq 2 ] ); then

Кстати, вы можете использовать Shell-Arithmetic ((...)):

if (( $#!=1 && $#!=2 )); then
2 голосов
/ 26 февраля 2012

Обратите внимание, что вы выполняете 2 команды в:

[ $# -ne 1 ] || [ $# -ne 2 ]

[ $# -ne 1 ] является 1-й командой, а команда [ $# -ne 2 ] выполняется только в том случае, если предыдущая имеет ненулевой код ошибки наоператор оболочки ||.

В вашем случае это не важно, но в приведенном ниже случае это:

[ $? -eq 0 ] || [ $? -eq 1 ]

2-я команда всегда будет истинной, так как2-й $? - это код возврата [ $? -eq 0 ].Вы можете проверить это с помощью строк ниже, которые будут печатать true дважды:

function f() { return $1; }
f 1
{ [ $? -eq 0 ] || [ $? -eq 1 ]; } && echo "true"
f 2
{ [ $? -eq 0 ] || [ $? -eq 1 ]; } && echo "true"

Правильный способ выполнения or в одной команде:

[ $? -eq 0 -o $? -eq 1 ]

ЭтоКстати, те, что ниже, печатают true один раз:

function f() { return $1; }
f 1
{ [ $? -eq 0 -o $? -eq 1 ]; } && echo "true"
f 2
{ [ $? -eq 0 -o $? -eq 1 ]; } && echo "true"

А что касается вашего первоначального вопроса, kev уже указал, что в вашем тесте была логическая ошибка.Отрицательное значение [ $# -eq 1 ] || [ $# -eq 2 ] равно NOT [ $# -eq 1 ] && NOT [ $# -eq 2 ] и становится [ $# -ne 1 ] && [ $# -ne 2 ] или одной командой:

[ $# -ne 1 -a $# -ne 2 ]
0 голосов
/ 26 февраля 2012

Один из способов выполнить эту работу - отключить оператор сравнения -ne для -lt и -gt ( меньше и больше) для условного оператора,Как это:

#!/bin/bash

#Should run if there are either 1 or 2 options specified
if [ $# -lt 1 ] || [ $# -gt 2 ]; then
    echo "usage: ${0##*/} <username>"
    exit
fi
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...