Co oznacza ostatni „-” (łącznik) w opcjach „bash”?

15

W tym samouczku musimy wykonać następujące polecenie:

# curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

Co oznacza ostatni -(łącznik) po bash?

Widziałem wiele poleceń z tym i nie mogłem znaleźć logicznego wyjaśnienia, a także nie znalazłem sposobu, aby przeformułować wyszukiwanie google. Czy jest to wynik polecenia potokowego?

Omar BISTAMI
źródło
5
To samo pytanie w Ask Ubuntu - z tym samym przykładem!
200_success
2
Pobieranie rzeczy z sieci i przesyłanie ich bezpośrednio do sudo bashdźwięków jest naprawdę przerażające. Spróbuj poszukać samouczka, który nie zachęca do takich praktyk.
Hmakholm pozostawił Monikę
To samouczek npm, ale zgadzam się z tobą ...
Omar BISTAMI,
1
Jeśli chcesz szukać rzeczy z symbolami, spróbuj symbolhound.com.
Joe

Odpowiedzi:

31

Bash zachowuje się w nieco niestandardowy sposób -.

POSIX mówi:

Wytyczna 10:
Pierwszy --argument, który nie jest argumentem opcji, powinien zostać zaakceptowany jako separator wskazujący koniec opcji. Wszelkie poniższe argumenty należy traktować jak operandy, nawet jeśli zaczynają się od -znaku.

[…]

Wytyczna 13:
W przypadku narzędzi, które używają argumentów do reprezentowania plików, które mają zostać otwarte w celu odczytu lub zapisu, -należy używać tego argumentu tylko w przypadku standardowego wejścia (lub standardowego wyjścia, gdy z kontekstu wynika, że ​​określono plik wyjściowy) lub plik o nazwie -.

I

W przypadku gdy narzędzie opisane w tomie Shell and Utilities POSIX.1-2017 jako zgodne z niniejszymi wytycznymi jest wymagane do zaakceptowania lub nieakceptowania argumentu -oznaczającego standardowe wejście lub wyjście, użycie to wyjaśniono w sekcji OPERANDS. W przeciwnym razie, jeśli takie narzędzie używa operandów do reprezentowania plików, określa się implementację, czy operand -oznacza standardowe wejście (lub standardowe wyjście), czy plik o nazwie -.

Ale potem man 1 bashczyta:

A --sygnalizuje koniec opcji i wyłącza dalsze przetwarzanie opcji. Wszelkie argumenty występujące po --są traktowane jako nazwy plików i argumenty. Argument -jest równoważny z --.

Tak więc dla Bash -nie oznacza ani standardowego wejścia, ani pliku, stąd nieco niestandardowy.

Teraz twój konkretny przypadek:

curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

I podejrzewam, autor tego polecenia nie może zrozumieć, -jest równoważne --w tej sprawie. I podejrzewam, autor chciał się upewnić, bashbędzie czytać ze standardowego wejścia, ale oczekuje -się pracy zgodnie z wytyczną 13.

Ale nawet gdyby działało zgodnie z wytycznymi, -byłoby tutaj niepotrzebne, ponieważ bashwykrywa, kiedy jego standardowym wejściem jest potok i działa odpowiednio (chyba że -cpodano itp.).

Jednak -nie działa zgodnie z wytycznymi, działa jak --. Nadal --jest tutaj niepotrzebny, ponieważ po nim nie ma żadnych argumentów.

Moim zdaniem ostatnie -nic nie zmienia. Polecenie działałoby bez niego.

Aby zobaczyć, jak --i -może być ogólnie użyteczne, przestudiuj poniższy przykład.


catw moim Kubuntu przestrzega obu wytycznych i użyję go do wykazania przydatności -i --.

Pozwól plikowi o nazwie fooistnieć. Spowoduje to wydrukowanie pliku:

cat foo

Pozwól plikowi o nazwie --helpistnieć. Nie spowoduje to wydrukowania pliku:

cat --help

Ale spowoduje to wydrukowanie pliku o nazwie --help:

cat -- --help

Spowoduje to konkatenację pliku o nazwie --helpz tym, co pochodzi ze standardowego wejścia:

cat -- --help -

Wygląda na to, że tak naprawdę nie potrzebujesz --, ponieważ zawsze możesz przekazać, ./--helpco z pewnością zostanie zinterpretowane jako plik. Ale zastanów się

cat "$file"

gdy nie wiesz z góry, jaka jest zawartość zmiennej. Nie możesz po prostu się ./do tego przyłączyć , ponieważ może to być ścieżka absolutna i ./mogłaby ją złamać. Z drugiej strony może to być plik o nazwie --help(bo dlaczego nie?). W tym przypadku --jest bardzo przydatny; jest to o wiele bardziej niezawodne polecenie:

cat -- "$file"
Kamil Maciorowski
źródło
6

W man bash, na końcu opcji jednoznakowych znajduje się:

--    A -- signals the end of options and disables further option processing.
      Any arguments after the -- are treated as filenames and arguments. An
      argument of - is equivalent to --.

Jeśli cytowany kompletny polecenia, widzę żadnego powodu do stosowania -po bashw tym przypadku, ale to nie szkodzi.

AFH
źródło
Dziękuję za odpowiedź. Tak, zacytowałem całe polecenie. więc cokolwiek po - lub - nie będzie postrzegane jako opcja, ale jako nazwa pliku lub argumenty, czy możesz podać przykład, w którym jest to przydatne?
Omar BISTAMI,
1
To naprawdę pozwala na skrypt, którego nazwa zaczyna się -, co jest mało prawdopodobne, ale -/ --umożliwia.
AFH
1
@OmarBISTAMI Cytując polecenie, wpłynie na sposób jego rozszerzenia przez powłokę, ale nie wpłynie na żaden z następujących po nim argumentów. Jeśli rozszerzysz cudzysłowy na uzasadnione argumenty, stają się one częścią nazwy polecenia, co też nie jest tym, czego chcesz. Istnieje kilka poleceń, które przyjmują nazwy plików jako argumenty, ale domyślnie nie używają standardowych danych wejściowych. Opracowany przykład pozwala na umieszczenie danych wejściowych (z terminala lub potoku) między dwoma plikami. cat file1 - file2 > file3.
Joe
1
curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

bash -oznacza, że bashczeka na standardowe wejście. Więc praktycznie bash wykona wszystko, co zwróci polecenie po lewej stronie|

Podobny, ale łatwiejszy przykład to:

echo hello | cat - tutaj catwydrukuje „cześć”. Dlaczego? Ponieważ „cześć” jest wysyłane do kota |i catczeka na wszystko, co do niego zostanie wysłane

Teraz podzielmy całe polecenie na dwa:

curl -sL https://rpm.nodesource.com/setup_6.x

to polecenie curl zwróci coś, co można zrozumieć i wykonać przez bash

wtedy mamy potok, |który wyśle ​​wynik zwracany przez polecenie curl na prawą stronę potoku, tj sudo -E bash -. Wreszcie sudo -E bash -, bash jest gotowy do wykonania wszystkiego, co zostanie do niego wysłane

Haris Muzaffar
źródło