Zawsze jestem zaskoczony, że w folderze /bin
jest [
program.
Czy tak się nazywa, gdy robimy coś takiego if [ something ]
:?
Wywołując [
program jawnie w powłoce, prosi o odpowiedni ]
, a kiedy dostarczam nawias zamykający, wydaje się, że nie robi nic, bez względu na to, co wstawię między nawiasy.
Nie trzeba dodawać, że zwykły sposób uzyskiwania pomocy na temat programu nie działa, tzn. Ani man [
nie [ --help
działa.
[
odnosi się dotest
polecenia, ale nieexpr
powinno tak byćman test
man '['
działa dla mnie dobrze - albo zapomniałeś zacytować,[
albo masz inną definicję „dzieł”.[
ocenia swoje argumenty, więc musisz mieć spacje między nimi wszystkimi.[ a=b ]
nie jest porównaniem: zawsze będzie prawdziwe (jest to pojedynczy ciąg: „a = b”, który zawsze jest oceniany jako prawda ) I powinieneś ograniczyć liczbę argumentów do 4 (nawet jeśli ostatnie implementacje pozwolą na więcej .. , ograniczenie do 4. czyni go bardziej przenośnym, na przykład:[ "a" = "b" ]
ma już 4 argumenty: „a” „=„ „b” i niepotrzebny koniec testu arg: „]”). Jeśli potrzebujesz więcej: testy łańcuchowe, na przykład:if [ "$Var_a" = "foo" ] && [ "$Var_b" = "bar" ] ; then : do something ; fi
!
sam (bez kształtów i bez cudzysłowów) nie zostanie zastąpiony, a nawet lepiejif ! [ ...
. Wszystkie używane rozszerzenia bash!
obejmują przynajmniej inną postać[
-builtin wbash
(i ewentualnie także innych powłokach), i że można go użyć zamiast/bin/[
. Istnieje równieżtest
polecenie, które w wielu systemach jest dowiązaniem symbolicznym do/bin/[
(lub odwrotnie), ale w innych jest osobnym poleceniem.Odpowiedzi:
Zadaniem tego
[
polecenia jest ocena wyrażeń testowych. Zwraca ze statusem wyjścia 0 (co oznacza prawda ), gdy wyrażenie przekształca się w prawda, a coś innego (co oznacza fałsz ) w przeciwnym razie.Nie chodzi o to, że nic nie robi, tylko o to, że jego wynikiem jest status wyjścia. W powłoce możesz dowiedzieć się o statusie zakończenia ostatniego polecenia w
$?
powłokach podobnych do Bourne'a lub$status
w większości innych powłok (fish / rc / es / csh / tcsh ...).W innych językach, takich jak
perl
, status wyjścia jest zwracany na przykład w wartości zwracanejsystem()
:Zauważ, że wszystkie współczesne powłoki podobne do Bourne'a (i
fish
) mają wbudowane[
polecenie. Ten w/bin
zwykle byłby wykonywany tylko wtedy, gdy używasz innej powłoki lub gdy robisz rzeczy takie jakenv [ foo = bar ]
lubfind . -exec [ -f {} ] \; -print
lub toperl
polecenie powyżej ...[
Polecenia jest również znany podtest
nazwą. Po wywołaniu jakotest
nie wymaga]
argumentu zamykającego .Chociaż twój system może nie mieć strony podręcznika
[
, prawdopodobnie ma jątest
. Ale znowu zauważ, że dokumentowałoby to/bin/[
lub/bin/test
wdrożenie. Aby dowiedzieć się o[
wbudowanej powłoce, powinieneś przeczytać dokumentację dla swojej powłoki.Aby uzyskać więcej informacji na temat historii tego narzędzia i różnicy w
[[...]]
wyrażeniu testowym ksh, możesz zajrzeć do innych pytań tutaj .źródło
[
. Nie pamiętam, czy był to wariant Bourne'a czy antyczna wersja popiołu.[
atest
jak builtins z System III. Wcześniej nie było[
itest
było tylko zewnętrzne polecenie binarne.find . -exec [ f {} ] \; -print
? Poleceniefind . -type f -print
zrobi to samo więc znacznie bardziej efektywnie ...Masz rację, że jesteś zaskoczony. To jedno z rzadkich poleceń POSIX z narzędziem zerowym (
:
), które nie przestrzega konwencji dozwolonych znaków w pliku poleceń (zestaw znaków w przenośnej nazwie pliku).Dokładnie, ale można go również używać bez
if
.Nie robi nic widocznego, ale w rzeczywistości robi to samo, co przy użyciu
if
, tzn. Ustawia status wyjścia na 0 (prawda) lub cokolwiek innego (fałsz) w zależności od tego, co umieścisz w nawiasach. Jest to (z jakiegoś powodu) to samo zachowanie, cotest
polecenie; jedyną różnicą jest to, że szuka zakończenia]
. Zobaczman test
szczegóły.To zależy od twojego systemu operacyjnego.
man [
zdecydowanie działa na mnie w kilku głównych dystrybucjach Gnu / Linux, ale nie działa w Solarisie.[ --help
może działać lub nie w zależności od implementacji, ponieważ i tak łamie składnię, brakuje jej zakończenia]
. Ponadto standardem POSIX dlatest
/[
polecenia wyraźnie wyklucza wszystkie opcje, w tym--
rozwiązaniu opcji tak jak[ --help ]
itest --help
potrzebne, aby powrócićtrue
i być cicho przez projekt. Zauważ, że to, co można umieścić w nawiasie lub później[
i że wygląda opcji (np-f file
,-n string
i lubi) nie są opcje , ale argumenty .Wszystkie nowoczesne style tłumaczy Bourne shell (jak
bash
,ksh
,dash
izsh
, aby wymienić tylko kilka) wdrożyćtest
/[
użyteczność jako wewnętrznie wbudowane więc podczas korzystania z nich, prawa strona podręcznika odnosi się do może być jednym z muszli, a nietest
jeden.Przed Unix System III (1981) powłoka Bourne'a nie implementowała
test
narzędzia jako wbudowanego, więc dostępna była tylko zewnętrzna implementacja poleceń binarnych.[
Do Uniksa System III nie było ani polecenia (wewnętrznego ani wbudowanego), więc na przykład w wersji 7 systemu Unix trzeba było wpisać:zamiast:
źródło
man test
działa, ale nieman [
Z drugiej strony moje środowisko cygwin wie o tymman [
!man [
wydaje się nie działać na Manjaro (oparty na Arch Linux). Podręcznik dlatest
list[ --help
jako prawidłowego wywołania, które powinno pokazywać pomoc, ale co ciekawe nie, i zamiast tego narzeka na brakujące]
, tak jak z--version
. Dodanie]
nic nie robi, więc wydaje się niemożliwe uzyskanie pomocy innej niżman test
./usr/bin/[ --help
lub/bin/[ --help
.env [ --help
jak również/usr/bin/[ --help
działa całkowicie dobrze (chociaż muszę cytować/usr/bin/[
lub narzeka Zsh).[
jest właściwie bardziej znany jakotest
polecenie. Typowe użycie tego polecenia polega po prostu na ocenie wyrażeń i zwróceniu ich stanu - true lub false. Jest często używany wif-then-else-fi
instrukcjach, chociaż można go używać pozaif
instrukcjami, aby warunkowo uruchamiać inne polecenia za pośrednictwem powłoki&&
lub||
operatorów, podobnie jak w przypadku innych.Mówiąc dokładniej, ocena przekazywana jest do innych poleceń poprzez status wyjścia. Niektóre programy mogą zdecydować o wyprowadzeniu statusu wyjścia w celu oznaczenia różnego rodzaju zdarzeń - pomyślne zakończenie programu, błąd określonego typu występujący podczas wykonywania lub błędy składniowe. W przypadku
test
polecenia istnieją0
znaki prawdziwe i1
oznaczają fałsz. Jak zauważył Stephan, błędy składniowe dają status wyjścia2
.Jego lokalizacja zależy od twojego systemu, a także wyjaśnia, dlaczego nie widziałeś strony podręcznika użytkownika
man [
. Na przykład na FreeBSD jest poniżej/bin
. W systemie Linux (lub w moim szczególnym przypadku Ubuntu 16.04) jest on dostępny/usr/bin/
. Jeśli to zrobiszman [
lubman test
w systemie Linux, zobaczysz tę samą dokumentację otwartą. Ważne jest również, aby pamiętać, że twoja powłoka może mieć własną implementacjętest
.Należy również zauważyć, że polecenie to ma problemy , które implementacja powłoki Korna (powszechnie znana jako odwołanie do „wyrażenia warunkowego” z podwójnymi nawiasami kwadratowymi
[[ "$USER" = "root" ]]
) ma na celu rozwiązanie. Ta funkcja jest również używana przez inne powłoki, takie jakbash
izsh
.źródło
/usr/bin/
także dla Amazon Linux.W niektórych dystrybucjach (np. Ubuntu)
man [
następuje dowiązanie symboliczne dotest(1)
. W przypadku innych (np. Arch) tak nie jest. (Aletest
strona man również dokumentuje użycie[
)type -a [
pokazuje, że zarówno wbudowana jest powłoka, jak i plik wykonywalny.Wbudowany bash
[ --help
po prostu drukuje komunikat o błędzie. (Ale ponieważ jest to wbudowane narzędzie, możesz użyćhelp [
lub spojrzeć na stronę / dokumenty podręcznika bash)./usr/bin/[ --help
wypisuje wyjście pełnej pomocy (dla wersji GNU Coreutils), które zaczyna się od:a następnie opisuje dozwoloną składnię EXPRESSION.
Jest to kolejny sposób, w jaki mogłeś się tego dowiedzieć
[
itest
są one równoważne.BTW, jeśli programujesz dla bash (lub interaktywnie piszesz jednowierszowe), polecam
[[
zamiast[
. Jest lepiej na kilka sposobów, zobacz linki w odpowiedzi Serga.źródło
[
polecenie zwraca status wyjścia zero, jeśli wyrażenie zawarte w jego argumentach jest uważane za prawdziwe, a niezerowy status wyjścia, jeśli wyrażenie zawarte w jego argumentach jest uważane za fałszywe. Komunikat o błędzie również kończy się niepowodzeniem, jeśli jego ostatnim argumentem nie jest]
(odbywa się to wyłącznie z powodów estetycznych).Na przykład:
… Wyświetli:
Jednak bash i wiele innych powłok zazwyczaj nie wywołuje
/bin/[
(lub/usr/bin/[
) w tych przypadkach, ale zamiast tego wywołuje wbudowane polecenie z dokładnie takim samym zachowaniem (wyłącznie ze względu na wydajność). Aby wywołać/bin/[
(nie wbudowane surogate powłoki), musisz jawnie określić jego ścieżkę (np./bin/[ hello ]
Nie musisz poprzedzać prefiksem]
dirname ☺ ), lub skonfigurować powłokę, aby nie korzystała z wbudowanego surogatu (na przykładenable -n [
w bash).PS: Jak powiedziano w innych odpowiedziach,
[
jest to związane ztest
. Aletest
, w przeciwieństwie[
, nie wymaga]
jako ostatni argument (i nie oczekiwać, że w ogóle, dodając dodatkowy]
dotest
argumentów może spowodować, że nie z komunikatem o błędzie lub powrót złego rezultatu) . I można rozwiązać na tym samym pliku (na przykład jeden jest dowiązane ; w tym przypadku przekierowania zachowanie jest prawdopodobnie realizowane przez analizowanie obecnie zwany polecenia w / samego kodu) lub do innych plików. Ponieważ powłoka zwykle wywołuje również wbudowane zastępcze, chyba że ścieżka jest wyraźnie określona ( ) lub skonfigurowana tak, aby tego nie robić (/bin/test
/bin/[
test
[
test
/bin/test
enable -n test
).PPS: W przeciwieństwie do
test
i[
, modernif
nigdy nie jest prawdziwym plikiem. Jest to część składni powłoki (np. Bash):if commandA; then commandB; fi
(zamiast średników można użyć znaku nowej linii) powoduje,commandB
że zostanie wykonany tylko wtedy, gdy zostaniecommandA
zakończony z zerowym statusem. To idealnie pasuje do zachowaniatest
lub[
, pozwalając łączyć je w podobny sposóbif [ "$a" = foo ]; then …; fi
(lubif test "$a" = foo; then …; fi
- po prostu mniej czytelne) . Jednak współczesne skrypty często używają[[
zamiasttest
lub[
, który (jakoif
) nigdy nie jest prawdziwym plikiem, ale zawsze jest częścią składni powłoki.PPPS: Jeśli chodzi o
man
- nigdy nie oczekuj,man
że w każdym systemie plików będziesz mieć artykuł na temat każdej komendy. Informacje o niektórych (nawet „prawdziwe”, oparty na plikach) poleceń może brakować informacji o niektórych powłoki wbudowanych wtyczek może obecne nie tylko w artykule poświęconym konkretnej powłoce (to jest miejsce, gdzie na pewno znajdziemy informacje na temattest
,[
,if
,[[
). Mimo to wiele dystrybucji ma wyraźneman
artykuły dlatest
i[
. (O--help
, nie jest rozpoznawany ztest
oczywistego powodu: musi cicho obsługiwać przypadki, takie jaka=--help; test "$a"
; w niektórych dystrybucjach[ --help
(bez zamykania]
) nadal pokazuje pomoc, w niektórych nie.)źródło
if
było to polecenie do wersji Unix V6. Unix V7 (1979) przyszedł z powłoką Bourne'a (z jegoif-then-else-fi
konstrukcją) i nowymtest
poleceniem.