So führen Sie eine logische ODER-Verknüpfung in Shell-Skripten durch


571

Ich versuche eine einfache Zustandsprüfung durchzuführen, aber es scheint nicht zu funktionieren.

Wenn $#gleich 0oder größer als ist, 1dann sag hallo.

Ich habe die folgende Syntax ohne Erfolg ausprobiert:

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

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

Sie arbeiten beide für mich. Haben Sie eine Shell in der Shebang- Zeile angegeben?
Jason McCreary

1
@ Jason Ich habe die Shebang-Linie tatsächlich vergessen, aber ich habe sie gerade damit getestet und es hat nicht funktioniert.
Erdbeere

25
>ist die Ausgabeumleitung in sh / bash. Jetzt haben Sie wahrscheinlich eine Datei mit dem Namen 1.
Mark4o

Informationen zu Bash-Vergleichen finden Sie hier und hier in meinen Antworten auf frühere Fragen . Weitere Informationen zu Klammern, Doppelklammern und Doppelklammern finden Sie in meiner Antwort hier .
Bis auf weiteres angehalten.

Es funktioniert nicht, weil Sie den Vergleich falsch eingeben: Verwenden Sie "$ #" == "0" oder $ # -eq 0
ETech

Antworten:


987

Das sollte funktionieren:

#!/bin/bash

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

Ich bin nicht sicher, ob dies in anderen Shells anders ist, aber wenn Sie <,> verwenden möchten, müssen Sie sie wie folgt in doppelte Klammern setzen:

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

2
Ich bin mir nicht sicher, ob es in einer anderen Shell anders ist, aber in Bash, wenn Sie> oder <verwenden möchten, müssen Sie sie wie folgt in doppelte Klammern setzen: (("$ a" <"$ b"))
Codierung Bezirk

1
@Doug: Es ist nicht so, dass Unix sie nicht verwendet, es ist diese Bash und alle anderen Shells, die ich kenne, verwenden sie für die Eingabe / Ausgabe-Umleitung.
Cascabel

56

Dieser Code funktioniert für mich:

#!/bin/sh

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

Ich glaube nicht, dass sh "==" unterstützt. Verwenden Sie "=", um Zeichenfolgen zu vergleichen, und -eq, um Ints zu vergleichen.

man test

für mehr Details.


Was ist die Option für größer als? Wo ist die offizielle Dokumentation für tihs?
Erdbeere

3
Sollte -gtfür größer sein als. Oder ersetzen Sie einfach alles durch [ $# -ne 1 ].
Mark4o

Größer als -gt, siehe meine Antwort. Die offizielle Dokumentation befindet sich im Man-Test, wie jbremnant hervorgehoben hat.
Coding District

Genau wie ein Fyi für andere, abhängig von Ihrer Shell, unterstützen die meisten == (jetzt ein paar Tage) als Vergleichsoperator, meistens jedoch ist es der gleiche wie der = -Operator. Ich würde mir vorstellen, dass es besser ist, -eq für == oder = zu verwenden, wenn Sie -gt und -ne für Vergleiche verwenden, um Ihren Skriptstil konsistent zu halten. Happy Bashing :)
jkdba

34

Wenn Sie den Bash-Exit-Code Status $ verwenden? Als Variable ist es besser, dies zu tun:

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

Denn wenn Sie dies tun:

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

Der linke Teil des OP verändert das $? variabel, also hat der rechte Teil des OP nicht das ursprüngliche $? Wert.


2
$ # gibt die Anzahl der an das Skript übergebenen Argumente zurück. Nützlich zur Überprüfung der korrekten Verwendung. Es scheint nicht, dass der Fragesteller Exit-Codes verwendet.
Centimane

27

Manchmal müssen Sie doppelte Klammern verwenden, andernfalls erhalten Sie einen Fehler wie zu viele Argumente

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

1
Dies ist nützlich, da ich hier nur ein Beispiel für nicht ganzzahlige Vergleiche sehe, die sich in der Syntax geringfügig unterscheiden.
Christopher Hunter

13

Wenn ein Bash-Skript

If [[ $input -gt number  ||  $input  -lt number  ]]
then 
    echo .........
else
    echo .........

fi

exit

7

Haben Sie so etwas versucht:

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

Ja, habe ich. Es ist echohallo, auch wenn ich ein einziges Argument habe.
Erdbeere

Der zweite $#könnte der Rückgabewert des ersten Tests sein?
Luckydonald

5

Aus dem Bash-Referenzhandbuch → 3.4.2 Spezielle Parameter

#
($ #) Wird auf die Anzahl der Positionsparameter in Dezimalzahl erweitert.

Daher $#wird immer entweder 0 oder eine größere Ganzzahl sein.

Wenn Sie also etwas tun möchten, wenn $#0 oder größer als 1 ist, müssen Sie nur überprüfen, ob dies der Fall $#ist oder nicht 1:

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

Dies verwendet die Syntax:

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

in bash können Sie etwas tun wie:[[ -n $A ]] && echo 1 || echo 2
premek.v

@ premek.v danke für den Kommentar. Meine Antwort wurde sehr schlecht erklärt, ich habe sie nur bearbeitet, in der Hoffnung, dass sie mehr Licht in das Thema bringt.
Fedorqui 'SO hör auf zu schaden'

1

Und in Bash

 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

ODER in Bash

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.