O que o último “-” (hífen) significa nas opções de `bash`?

15

Em este tutorial que precisamos para executar o seguinte comando:

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

O que significa o último -(hífen) depois bash?

Eu já vi muitos comandos com isso, e não consegui encontrar uma explicação lógica nem descobrir como reformular uma pesquisa no Google. É a saída do comando canalizado?

Omar BISTAMI
fonte
5
A mesma pergunta no Ask Ubuntu - com o mesmo exemplo!
200_success
2
Baixar coisas da rede e canalizá-las diretamente para sudo bashsons realmente assustadores. Tente procurar um tutorial que não incentive essas práticas.
hmakholm saiu sobre Monica
É o tutorial npm, mas eu concordo com você ...
Omar Bistami
11
Se você precisar procurar itens com símbolos, tente symbolhound.com.
Joe

Respostas:

31

O Bash se comporta de maneira um pouco fora do padrão -.

O POSIX diz:

Diretriz 10:
O primeiro --argumento que não é um argumento de opção deve ser aceito como um delimitador indicando o final das opções. Quaisquer argumentos a seguir devem ser tratados como operandos, mesmo se começarem com o -caractere.

[...]

Diretriz 13:
Para utilitários que usam operandos para representar arquivos a serem abertos para leitura ou gravação, o -operando deve ser usado para significar apenas entrada padrão (ou saída padrão quando estiver claro no contexto que um arquivo de saída está sendo especificado) ou um arquivo nomeado -.

E

Quando um utilitário descrito no volume Shell e Utilitários do POSIX.1-2017, em conformidade com estas diretrizes, é necessário para aceitar ou não aceitar, o operando -para significar entrada ou saída padrão, esse uso é explicado na seção OPERANDS. Caso contrário, se esse utilitário usar operandos para representar arquivos, será definido pela implementação se o operando -representa entrada padrão (ou saída padrão) ou um arquivo nomeado -.

Mas então man 1 bashlê:

A --sinaliza o fim das opções e desativa o processamento adicional das opções. Quaisquer argumentos após o --são tratados como nomes de arquivos e argumentos. Um argumento de -é equivalente a --.

Portanto, para Bash -não significa entrada padrão nem arquivo, portanto, algo fora do padrão.

Agora seu caso particular:

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

Eu suspeito que o autor deste comando pode não perceber que -é equivalente a --neste caso. Eu suspeito que o autor queria ter certeza bashirá ler a partir de sua entrada padrão, que esperavam -para trabalhar de acordo com a diretriz 13.

Mas, mesmo que funcionasse de acordo com a diretriz, -seria desnecessário aqui porque bashdetecta quando sua entrada padrão é um tubo e age de acordo (a menos que -cseja fornecido etc.).

No entanto -, não funciona de acordo com a diretriz, funciona como --. Ainda --é desnecessário aqui porque não há argumentos após isso.

Na minha opinião, a última -não muda nada. O comando funcionaria sem ele.

Para ver como --e -pode ser útil em geral, estude o exemplo abaixo.


catno meu Kubuntu obedece a ambas as diretrizes e vou usá-lo para demonstrar a utilidade de -e --.

Deixe um arquivo chamado fooexistir. Isso imprimirá o arquivo:

cat foo

Deixe um arquivo chamado --helpexistir. Isso não imprimirá o arquivo:

cat --help

Mas isso imprimirá o arquivo chamado --help:

cat -- --help

Isso concatenará o arquivo nomeado --helpcom o que vier da entrada padrão:

cat -- --help -

Parece que você realmente não precisa --, porque você sempre pode passar o ./--helpque será interpretado como um arquivo, com certeza. Mas considere

cat "$file"

quando você não sabe de antemão qual é o conteúdo da variável. Você não pode simplesmente anexá ./-lo a ele, porque pode ser um caminho absoluto e ./o quebraria. Por outro lado, pode ser um arquivo chamado --help(porque por que não?). Neste caso --é muito útil; este é um comando muito mais robusto:

cat -- "$file"
Kamil Maciorowski
fonte
6

Em man bash, no final das opções de um caractere, há: -

--    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 --.

Se você citou o comando completo, não vejo motivo para usá-lo -posteriormente bash, mas não faz mal.

AFH
fonte
Obrigado pela sua resposta, Sim, citei o comando completo. portanto, qualquer coisa depois - ou - não será vista como uma opção, mas como um nome de arquivo ou argumentos, você poderia dar um exemplo em que é útil?
Omar BISTAMI
11
É realmente para permitir um script cujo nome começa -, um requisito improvável, mas -/ --torna possível.
AFH
11
@OmarBISTAMI A citação de um comando afetará como o shell o expande, mas não afeta nenhum dos argumentos que o seguem. Se você estender as aspas em torno de argumentos legítimos, eles se tornarão parte do nome do comando, que também não é o que você deseja. Existem alguns comandos que usam nomes de arquivos como argumentos, mas não usam entrada padrão por padrão. Um exemplo artificial permite que você insira a entrada (de um terminal ou canal) entre dois arquivos. cat file1 - file2 > file3.
Joe
1
curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

bash -significa que bashestá esperando por stdin. Portanto, praticamente o bash executará o que for retornado pelo comando que está à esquerda de|

Um exemplo semelhante, porém mais fácil, seria:

echo hello | cat - aqui, catimprimirá 'olá'. Por quê? Porque 'olá' está sendo enviado para o gato |e catestá esperando por qualquer coisa enviada a ele

Agora vamos dividir o comando inteiro em dois:

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

este comando curl retornará algo que pode ser entendido e executado pelo bash

então nós temos um pipe |que enviará a saída retornada pelo comando curl para o lado direito do pipe ie sudo -E bash -. Finalmente sudo -E bash -, o bash está pronto para executar qualquer coisa que é enviada a ele

Haris Muzaffar
fonte