Як зробити логічну операцію АБО в сценарії оболонок


571

Я намагаюся зробити просту перевірку стану, але це, здається, не працює.

Якщо $#дорівнює 0або більше, ніж 1привітатися.

Я пробував наступний синтаксис без успіху:

if [ "$#" == 0 -o "$#" > 1 ] ; then
 echo "hello"
fi

if [ "$#" == 0 ] || [ "$#" > 1 ] ; then
 echo "hello"
fi

Вони обидва працюють на мене. Ви вказали оболонку в лінії shebang ?
Jason McCreary

1
@Jason Я насправді забув лінію shebang, але я протестував її зараз, і це не спрацювало.
Полуниця

25
>є вихідне перенаправлення в ш / баш. Зараз у вас, ймовірно, є файл з іменем 1.
mark4o

Для отримання інформації про порівняння Bash, будь ласка, дивіться мої відповіді на попередні запитання тут і тут . Для отримання додаткової інформації щодо дужок, подвійних дужок та подвійних дужок дивіться мою відповідь тут .
Призупинено до подальшого повідомлення.

Це не працює, тому що ви неправильно вводите порівняння: використовуйте "$ #" == "0" або $ #
-eq

Відповіді:


987

Це має працювати:

#!/bin/bash

if [ "$#" -eq 0 ] || [ "$#" -gt 1 ] ; then
    echo "hello"
fi

Я не впевнений, чи відрізняється це в інших оболонках, але якщо ви хочете використовувати <,>, вам потрібно помістити їх у подвійні дужки так:

if (("$#" > 1))
 ...

2
Я не впевнений, чи відрізняється він в іншій оболонці, але в bash, якщо ви хочете використовувати> або <, ви повинні помістити їх у подвійні дужки так: (("$ a" <"$ b"))
Кодування Округ

1
@Doug: Це не те, що unix не використовує їх, це той баш і всі інші оболонки, які я знаю, використовують їх для перенаправлення вводу / виводу.
Каскабель

56

Цей код працює для мене:

#!/bin/sh

argc=$#
echo $argc
if [ $argc -eq 0 -o $argc -eq 1 ]; then
  echo "foo"
else
  echo "bar"
fi

Я не думаю, що sh підтримує "==". Використовуйте "=" для порівняння рядків і -eq для порівняння ints.

man test

для отримання детальної інформації.


Що є варіантом для більшого? Де офіційна документація для цих?
Полуниця

3
Повинен бути -gtбільше. Або просто замінити все на [ $# -ne 1 ].
mark4o

Більше, ніж це - gt, дивіться мою відповідь. Офіційна документація є тестом на людину, як вказував jbremnant.
Кодування району

Так само, як фій для інших, залежно від вашої оболонки, більшість підтримує == (зараз це дні) як оператора порівняння, проте більшість часу це те саме, що і оператор =. Я б міг уявити, що якщо ви використовуєте -gt та -ne для порівнянь, то було б кращою практикою використовувати -eq for == або =, щоб ваш стиль сценаріїв був узгоджений. Happy
Bashing

34

Якщо ви використовуєте статус вихідного коду bash $? як змінна, краще це зробити:

if [ $? -eq 4 -o $? -eq 8 ] ; then  
   echo "..."
fi

Тому що якщо ви робите:

if [ $? -eq 4 ] || [ $? -eq 8 ] ; then  

Ліва частина або змінює $? змінна, тож права частина АБО не має оригіналу $? значення.


2
$ # повертає кількість аргументів, переданих сценарію. Корисно для перевірки правильності використання. Не здається, що запитувач використовує коди виходу.
Centimane

27

Іноді потрібно використовувати подвійні дужки, інакше ви отримуєте помилку, як занадто багато аргументів

if [[ $OUTMERGE == *"fatal"* ]] || [[ $OUTMERGE == *"Aborting"* ]]
  then
fi

1
Це корисно, тому що це єдине, що я бачу, показуючи приклад не цілих порівнянь, які за синтаксисом трохи відрізняються.
Крістофер Хантер


7

ви пробували щось подібне:

if [ $# -eq 0 ] || [ $# -gt 1 ] 
then
 echo "$#"
fi

Так, у мене є. Це echoS привіт , навіть якщо у мене є один аргумент.
Полуниця

Другим $#може бути повернене значення першого тесту?
везунчик

5

З Довідкового посібника Баша → 3.4.2 Спеціальні параметри

#
($ #) Розширюється на кількість позиційних параметрів у десятковій частині.

Тому $#завжди буде або 0, або більше ціле число.

Тож якщо ви хочете щось робити щоразу, коли $#це 0 або перевищує 1, вам просто потрібно перевірити, $#є чи ні 1:

[ $# -eq 1 ] && echo "1 positional param" || echo "0 or more than 1"

Для цього використовується синтаксис:

[ condition ] && {things if true} || {things if false}

в [[ -n $A ]] && echo 1 || echo 2
баші

@ premek.v дякую за коментар. Моя відповідь була дуже погано пояснена, я просто редагував її, сподіваючись, що вона прожене більше теми.
fedorqui 'ТАК перестаньте шкодити'

1

І в Баші

 line1=`tail -3 /opt/Scripts/wowzaDataSync.log | grep "AmazonHttpClient" | head -1`
 vpid=`ps -ef|  grep wowzaDataSync | grep -v grep  | awk '{print $2}'`
 echo "-------->"${line1}
    if [ -z $line1 ] && [ ! -z $vpid ]
    then
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Process Is Working Fine"
    else
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Prcess Hanging Due To Exception With PID :"${pid}
   fi

АБО в Баш

line1=`tail -3 /opt/Scripts/wowzaDataSync.log | grep "AmazonHttpClient" | head -1`
vpid=`ps -ef|  grep wowzaDataSync | grep -v grep  | awk '{print $2}'`
echo "-------->"${line1}
   if [ -z $line1 ] || [ ! -z $vpid ]
    then
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Process Is Working Fine"
    else
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Prcess Hanging Due To Exception With PID :"${pid}
  fi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.