Que signifie le dernier «-» (trait d'union) dans les options de «bash»?

15

Dans ce tutoriel, nous devons exécuter la commande suivante:

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

Que signifie le dernier -(trait d'union) après bash?

J'ai vu beaucoup de commandes avec cela, et je n'ai pas pu trouver d'explication logique ni trouver comment reformuler une recherche Google pour cela. Est-ce la sortie de la commande piped?

Omar BISTAMI
la source
5
Même question sur Ask Ubuntu - avec le même exemple!
200_success
2
Télécharger des trucs du réseau et les transférer directement dans des sudo bashsons vraiment effrayants. Essayez de rechercher un didacticiel qui n'encourage pas de telles pratiques.
hmakholm a quitté Monica
C'est le tutoriel npm, mais je suis d'accord avec vous ...
Omar BISTAMI
1
Si vous devez rechercher des éléments contenant des symboles, essayez symbolhound.com.
Joe

Réponses:

31

Bash se comporte de manière quelque peu non standard en ce qui concerne -.

POSIX dit:

Ligne directrice 10:
Le premier --argument qui n'est pas un argument d'option doit être accepté comme délimiteur indiquant la fin des options. Tous les arguments suivants doivent être traités comme des opérandes, même s'ils commencent par le -caractère.

[…]

Directive 13:
Pour les utilitaires qui utilisent des opérandes pour représenter les fichiers à ouvrir en lecture ou en écriture, l' -opérande doit être utilisé pour signifier uniquement une entrée standard (ou une sortie standard lorsqu'il est clair d'après le contexte qu'un fichier de sortie est spécifié) ou un fichier nommé -.

Et

Lorsqu'un utilitaire décrit dans le volume Shell et utilitaires de POSIX.1-2017 comme conforme à ces directives doit accepter ou ne pas accepter l'opérande -pour signifier une entrée ou une sortie standard, cette utilisation est expliquée dans la section OPERANDES. Sinon, si un tel utilitaire utilise des opérandes pour représenter des fichiers, il est défini par l'implémentation si l'opérande -représente l'entrée standard (ou la sortie standard) ou un fichier nommé -.

Mais man 1 bashlit ensuite :

A --signale la fin des options et désactive le traitement des options. Tous les arguments après le --sont traités comme des noms de fichiers et des arguments. Un argument de -est équivalent à --.

Donc pour Bash -ne signifie ni entrée standard ni fichier, donc quelque peu non standard.

Maintenant, votre cas particulier:

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

Je soupçonne que l'auteur de cette commande peut ne pas réaliser que -c'est équivalent --dans ce cas. Je soupçonne que l'auteur voulait s'assurer de bashlire à partir de son entrée standard, ils s'attendaient- à travailler selon la directive 13.

Mais même si cela fonctionnait selon la directive, ce -serait inutile ici car il bashdétecte quand son entrée standard est un tuyau et agit en conséquence (sauf-c etc.).

Pourtant, -ne fonctionne pas selon la directive, cela fonctionne comme --. C'est encore --inutile ici car il n'y a pas d'arguments après.

À mon avis, le dernier -ne change rien. La commande fonctionnerait sans elle.

Pour voir comment --et -peuvent être utiles en général, étudiez l'exemple ci-dessous.


catdans mon Kubuntu obéit aux deux directives et je vais l'utiliser pour démontrer l'utilité de -et --.

Laissez un fichier nommé fooexister. Cela imprimera le fichier:

cat foo

Laissez un fichier nommé --helpexister. Cela n'imprimera pas le fichier:

cat --help

Mais cela imprimera le fichier nommé --help:

cat -- --help

Cela concaténera le fichier nommé --helpavec tout ce qui provient de l'entrée standard:

cat -- --help -

Il semble que vous n'en ayez pas vraiment besoin --, car vous pouvez toujours passer ./--helpce qui sera interprété comme un fichier à coup sûr. Mais considérez

cat "$file"

lorsque vous ne savez pas à l'avance quel est le contenu de la variable. Vous ne pouvez pas simplement y ajouter un préfixe ./, car il peut s'agir d'un chemin absolu ./qui le briserait. Par contre il peut s'agir d'un fichier nommé --help(car pourquoi pas?). Dans ce cas, --est très utile; c'est une commande beaucoup plus robuste:

cat -- "$file"
Kamil Maciorowski
la source
6

Dans man bash, à la fin des options à un caractère, il y a: -

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

Si vous avez cité la commande complète, je ne vois aucune raison de l'utiliser -après bashdans ce cas, mais cela ne fait aucun mal.

AFH
la source
Merci pour votre réponse, oui j'ai cité la commande complète. donc quoi que ce soit après - ou - ne sera pas considéré comme une option mais comme un nom de fichier ou des arguments, pourriez-vous s'il vous plaît donner un exemple où il est utile?
Omar BISTAMI
1
Il est vraiment de permettre un script dont le nom commence -, une exigence peu probable, mais -/ --permet.
AFH
1
@OmarBISTAMI La citation d'une commande affectera la façon dont le shell la développe, mais n'affectera aucun des arguments qui la suivent. Si vous étendez les guillemets autour d'arguments légitimes, ils deviennent alors une partie du nom de la commande qui n'est pas non plus ce que vous voulez. Certaines commandes prennent les noms de fichiers comme arguments, mais n'utilisent pas d'entrée standard par défaut. Un exemple artificiel vous permet de prendre en sandwich l'entrée (à partir d'un terminal ou d'un tuyau) entre deux fichiers. cat file1 - file2 > file3.
Joe
1
curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

bash -signifie qui bashattend stdin. Donc, pratiquement bash exécutera tout ce qui est retourné par la commande qui se trouve à gauche de|

Un exemple similaire mais plus simple serait:

echo hello | cat - ici, catimprimera «bonjour». Pourquoi? Parce que «bonjour» est envoyé au chat |et catattend tout ce qui lui est envoyé

Maintenant, divisons la commande entière en deux:

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

cette commande curl retournera quelque chose qui peut être compris et exécuté par bash

alors nous avons un tuyau |qui enverra la sortie retournée par la commande curl vers le côté droit du tuyau, c'est-à-dire sudo -E bash -. Enfin sudo -E bash -, bash est prêt à exécuter tout ce qui lui est envoyé

Haris Muzaffar
la source