Jeśli piszę
::
w bash shell otrzymuję:
-bash: ::: command not found
Ale tylko jeden :powoduje brak wyników. Dlaczego to?
Jeśli piszę
::
w bash shell otrzymuję:
-bash: ::: command not found
Ale tylko jeden :powoduje brak wyników. Dlaczego to?
Odpowiedzi:
:Shell wbudowaną vs nieistniejące::: Powłoka wbudowane polecenie istnieje (zwróć uwagę na różnicę pomiędzy zewnętrznym i wbudowanych komend ), który nic nie robi; po prostu zwraca sukces, tak jak truepolecenie. :Wbudowany jest standardowe i zdefiniowane przez standard POSIX , gdzie jest znany również jako „narzędzia” zerowej. Jest często używany do testowania lub uruchamiania nieskończonych pętli jak wwhile : ; do ...;done
bash-4.3$ type :
: is a shell builtin
Jednak ::- dwa znaki dwukropka razem - są interpretowane jako jedno „słowo” dla powłoki i zakłada się, że jest to polecenie wprowadzone przez użytkownika. Powłoka przejdzie proces sprawdzania wbudowanych, a następnie dowolnego katalogu w PATHzmiennej pod kątem istnienia tego polecenia. Ale nie ma wbudowanego :: ani zewnętrznego polecenia ::. Dlatego powoduje to błąd.
Jaki jest typowy format błędu?
<shell>: <command user typed>: error message
Zatem to, co widzisz, nie jest 3 dwukropkami, ale to, co wpisałeś, wkleiło się do standardowego formatu błędu.
Zauważ też, że :mogą przyjmować argumenty wiersza poleceń, tzn. Legalne jest:
: :
W takim przypadku powłoka uzna to za dwa „słowa”, z których jedno jest poleceniem, a drugie parametrem pozycyjnym. To również nie spowoduje błędu! (Zobacz także notę historyczną (w dalszej części tej odpowiedzi) na temat używania :parametru z parametrami pozycyjnymi).
Pamiętaj, że formatowanie może również różnić się w zależności od powłoki. Dla bash, kshi mkshzachowanie jest spójne. Na przykład domyślna /bin/shpowłoka Ubuntu (która jest w rzeczywistości /bin/dash):
$ dash
$ ::
dash: 1: ::: not found
gdzie 1 to numer polecenia (odpowiednik numeru wiersza w skrypcie).
csh dla kontrastu nie generuje żadnego komunikatu o błędzie:
$ csh
% ::
%
W rzeczywistości, jeśli uruchomisz strace -o csh.trace csh -c ::, dane wyjściowe śledzenia w csh.tracepliku ujawnią, że cshkończy się ze statusem wyjścia 0 (bez błędów). Ale tcshgeneruje błąd (jednak bez wypisywania swojej nazwy):
$ tcsh
localhost:~> ::
::: Command not found.
Ogólnie rzecz biorąc, pierwszym elementem w komunikacie o błędzie powinien być proces lub funkcja wykonująca (powłoka próbuje wykonać ::, dlatego komunikat o błędzie pochodzi z powłoki). Na przykład tutaj proces wykonawczy to stat:
$ stat noexist
stat: cannot stat 'noexist': No such file or directory
W rzeczywistości POSIX definiuje funkcję perror () , która zgodnie z dokumentacją przyjmuje argument łańcuchowy, a następnie wyświetla dwukropek komunikat o błędzie, a następnie znak nowej linii. Zacytować:
Funkcja perror () odwzorowuje numer błędu dostępny poprzez symbol errno na zależny od języka komunikat o błędzie, który należy zapisać w standardowym strumieniu błędów w następujący sposób:
Po pierwsze (jeśli s nie jest wskaźnikiem pustym, a znak wskazywany przez s nie jest bajtem pustym), ciąg wskazany przez s, po którym następuje dwukropek i <spacja>.
Następnie ciąg komunikatu o błędzie, po którym następuje <nowa linia>.
Argumentem łańcuchowym perror()technicznie może być cokolwiek, ale oczywiście dla jasności jest to zazwyczaj nazwa funkcji lub argv[0].
Z kolei GNU ma swój własny zestaw funkcji i zmiennych do obsługi błędów , z których programista może korzystać fprintf()do stderrstrumieniowania. Jak pokazuje jeden z przykładów na połączonej stronie, można zrobić coś takiego:
fprintf (stderr, "%s: Couldn't open file %s; %s\n",
program_invocation_short_name, name, strerror (errno));
W starej powłoce Uniksa i Thompsona :użyto gotoinstrukcji (która według użytkownika o nazwie Perderabo w tym wątku nie była wbudowaną powłoką). Cytat z instrukcji:
Cały plik poleceń jest przeszukiwany pod kątem linii rozpoczynającej się od: jako pierwszego niepustego znaku, po którym następuje jeden lub więcej spacji, a następnie etykieta. Jeśli taka linia zostanie znaleziona, goto przesuwa przesunięcie pliku poleceń do linii po etykiecie i kończy działanie. Powoduje to, że powłoka przechodzi do oznaczonej linii.
Możesz więc zrobić coś takiego, aby stworzyć nieskończony skrypt pętli:
: repeat
echo "Hello World"
goto repeat
command.comi Windows ' cmd.exemają podobną, ale odwrotną sytuację: :jest to wyraźnie etykieta goto (a nie polecenie) i często zmienia przeznaczenie jako znak komentarza (np :: This is a comment.).
Ostatni dwukropek jest tylko częścią domyślnego komunikatu „nie znaleziono”:
$ x
x: command not found
$ ::
::: command not found
Powodem, dla którego pojedynczy dwukropek nie produkuje nic, : jest prawidłowe polecenie - chociaż nie robi nic (oprócz powrotu TRUE). Z SHELL BUILTIN COMMANDSsekcji man bash:
: [arguments]
No effect; the command does nothing beyond expanding arguments
and performing any specified redirections. A zero exit code is
returned.
Czasami zobaczysz to w konstrukcjach takich jak
while :
do
something
done
Zobacz na przykład Jaki jest cel wbudowanego dwukropka?
Dodany dwukropek jest częścią samego komunikatu o błędzie. Jeśli jeden wpisze cd ow, spowoduje to bash: cd: ow: No such file or directory, co pokazuje, że błąd polega na wstawieniu dodatkowego dwukropka: No such file or directory
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found
trzeci jest odstępem od formatowania
w bash a :jest pustą instrukcją void