Co robi wpisanie pojedynczego wykrzyknika w Bash?


20

Bash używa wykrzykników do rozszerzeń historii, jak wyjaśniono w odpowiedziach na to pytanie (np. sudo !!Uruchamia poprzedni wiersz poleceń sudo). Jednak nie mogę znaleźć nigdzie, co wyjaśnia, co robi następujące polecenie (np. Pojedynczy wykrzyknik):

!

Wygląda na to, że nic nie drukuje i wychodzi z 1, ale nie jestem pewien, dlaczego to robi. Szukałem online i na stronie podręcznika użytkownika Bash, ale nie mogę nic znaleźć, poza tym, że jest to „słowo zastrzeżone” - ale tak jest }i uruchamiam to:

}

wypisuje błąd:

bash: syntax error near unexpected token `}'

1
Nic. !wskazuje „początek” wyrażenia rozszerzenia historii.
jordanm

Odpowiedzi:


47

Samotny !na początku polecenia neguje status wyjścia polecenia lub potoku : jeśli polecenie wyjdzie 0, przejdzie w 1(niepowodzenie), a jeśli wyjdzie niezerowe, zamieni je w 0(pomyślne) wyjście.

Użycie to jest udokumentowane w podręczniku Bash:

Jeśli zarezerwowane słowo „!” poprzedza potok, status wyjścia jest logiczną negacją statusu wyjścia, jak opisano powyżej.

!Bez następującego polecenia neguje pusty komendę, która nic nie robi i zwraca true (równoważne z :poleceniem ). W ten sposób odwraca prawdę na fałsz i wychodzi ze statusem 1, ale nie powoduje błędu.


Istnieją także inne zastosowania !wewnątrz testi [[poleceń, gdzie one zniweczyć próbę warunkowego. Nie są one związane z tym, co widzisz. Zarówno w twoim pytaniu, jak i w tych przypadkach, nie jest to związane z rozszerzaniem historii i !jest oddzielone od innych terminów.


5
+1 za pierwszą odpowiedź wyjaśniającą, co jest faktycznie uruchomione i dlaczego wyjaśnia kod powrotu.
Jeff Schaller

11

Pojedynczy wykrzyknik można znaleźć w podręczniku bash w sekcji 3.2.2 Rurociągi

Jeśli zarezerwowane słowo „!” poprzedza potok, status wyjścia jest logiczną negacją statusu wyjścia, jak opisano powyżej.

$ ! true; echo $?
1
$ ! false; echo $?
0

Także sekcja 3.2.4.2 Konstrukcje warunkowe

! wyrażenie

Prawda, jeśli wyrażenie jest fałszywe.


Także sekcja 4.1 Wbudowane powłoki Bourne'a

! expr

Prawda, jeśli wyrażenie jest fałszem.


Należy również zauważyć, że !rozpocznie podstawianie historii, chyba że następuje po niej: spacja, tabulator, koniec linii, „=” lub „(” (gdy opcja powłoki extglob jest włączona przy użyciu wbudowanego shopt).


0

Ponieważ !jest używany w porównaniach i oznacza NIE .

Na przykład:

a=3
b=2

[ $a -eq $b ] && echo "Equal"
[ ! $a -eq $b ] && echo "Not equal"
# of cause last comparison is possible to write as:
[ $a -eq $b ] || echo "Not equal"

[ $a -eq $b ]
echo $?
1
[ ! $a -eq $b ]
echo $?
0

1
Takie jest znaczenie !argumentu testpolecenia (w tym wbudowanej wersji bash), a nie znaczenie, !gdy jest używany w pozycji polecenia.
Gilles 'SO - przestań być zły'

1
W takim przypadku konieczne będzie ! [...]dopasowanie pytania.
Michael Homer

Uzgodnione z @Gilles i @Michael Homer. Wiedziałem, że []tak test. Trochę się spieszę.
Yurij Goncharuk

-2

! wbudowane polecenie, odwraca sens potoku.

Inne zastosowania:

#! wbudowane polecenie, wywołuje nazwanego interpretera w celu wykonania skryptu.

! oznacznik zdarzenia oznacza słowo wiersza polecenia jako podstawienie historii

!= operator nierówności

$! zmienna powłoki, zwraca numer procesu ostatniego polecenia w tle.


Aby dodać, można użyć! $, Aby użyć ostatniego słowa poprzedniego polecenia w następujący sposób: ls -l /tmp cd !$ Spowoduje to przejście do katalogu / tmp.
Hopping Bunny,

-3

! następnie ciąg znaków wykonuje ostatnie poprzednie polecenie (wciąż w buforze poleceń), które rozpoczęło się od podanego ciągu. Być może powłoka właśnie odkryła, że żadne poprzednie polecenie nie zaczynało się od <null>.


3
Zauważyłeś, że w pytaniu nie było podanego ciągu ...?
Jeff Schaller
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.