nigdy nie używaj operatora `-a` lub` -o` z `[`

11

Stéphane Chazelas napisał:

kilka zasad takich jak

  • zawsze podawaj zmienne
  • Nigdy nie używać -aalbo -ooperatora (użyć kilku [poleceń oraz &&i ||powłoki operatorzy)

Bądź [niezawodny dzięki powłokom POSIX.

Dlaczego „nigdy nie należy używać operatora -alub -o”?

Jak mogę zrobić „używać kilku [poleceń oraz operatorów powłoki &&i ||”)?

Tim
źródło

Odpowiedzi:

13

Dlaczego „nigdy nie należy używać operatora -alub -o”?

Ponieważ mogą być wieloznaczne i dlatego nie są zgodne z POSIX :

Rozszerzenia XSI określające -a i -o binarne pozycje podstawowe oraz operatory „(” i „)” zostały oznaczone jako przestarzałe. (Wiele wyrażeń, które ich używają, są niejednoznacznie zdefiniowane przez gramatykę w zależności od ocenianych wyrażeń). Skrypty używające tych wyrażeń powinny zostać przekonwertowane na podane poniżej formy. Mimo że wiele implementacji będzie nadal obsługiwać te przestarzałe formularze, skrypty powinny zachować szczególną ostrożność, mając do czynienia z danymi wejściowymi dostarczanymi przez użytkowników, które można pomylić z tymi i innymi elementami podstawowymi i operatorami. O ile twórca aplikacji nie zna wszystkich przypadków, które generują dane wejściowe do skryptu, wywołania takie jak:

test "$1" -a "$2"

należy zapisać jako:

test "$1" && test "$2"

Jak mogę zrobić „używać kilku [poleceń oraz operatorów powłoki &&i ||”)?

Wykonując wiele testów i łącząc je za pomocą wspomnianych operatorów; na przykład:

[ 0 -eq 0 -a \( 0 -eq 1 -o 1 -eq 1 \) ]

można przepisać jako odpowiednik:

[ 0 -eq 0 ] && ([ 0 -eq 1 ] || [ 1 -eq 1 ])

albo lepiej:

[ 0 -eq 0 ] && { [ 0 -eq 1 ] || [ 1 -eq 1 ]; }
kos
źródło
dzięki. (1) „Operatory„ (”i„) ”zostały oznaczone jako przestarzałe”. Czy (i )operatorzy że grupa poleceń? Jeśli są przestarzałe, jakie są ich zamienniki? (2) Należy test "$1" -a "$2"zastąpić przez test "$1" && test "$2"lub ((test "$1" && test "$2"))? Czy nie potrzebujemy ((..))?
Tim
@ Tim Zobacz aktualizację. (1) Tak - możesz użyć ()i {}jako zamiennik. (2) pierwszy; (())służy do interpretacji arytmetycznej, tutaj chcesz przetestować status wyjścia łańcucha testów, więc albo zgrupuj testy w podpowłoce, ()albo w bieżącej powłoce {}.
Kos
Dzięki. Myślę, że moje pytania mogą wykraczać poza ten post. Więc zamieszczam je w nowym poście.
Tim
1
@Tim Jedynym powodem korzystania z operatorów (i )jest użycie -alub -o. Ponieważ te ostatnie są przestarzałe, te pierwsze oczywiście nie są już potrzebne.
Barmar