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


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.