Que signifie `(backquote / backtick) dans les commandes?

160

Je suis tombé sur la commande suivante:

sudo chown `id -u` /somedir

et je me demande: quelle est la signification du `symbole. J'ai remarqué par exemple que si la commande ci-dessus fonctionne bien, celle ci-dessous ne fonctionne pas:

sudo chown 'id -u' /somedir
gws
la source

Réponses:

201

Ceci est un backtick . Un backtick n'est pas un signe de citation. Cela a une signification très spéciale. Tout ce que vous tapez entre les backticks est évalué (exécuté) par le shell avant la commande principale (comme chowndans vos exemples), et la sortie de cette exécution est utilisée par cette commande, comme si vous tapiez cette sortie à cet endroit de la liste. ligne de commande.

Et alors

sudo chown `id -u` /somedir

fonctionne efficacement (en fonction de votre ID utilisateur ) est:

sudo chown 1000 /somedir
  \    \     \     \
   \    \     \     `-- the second argument to "chown" (target directory)
    \    \     `-- your user ID, which is the output of "id -u" command
     \    `-- "chown" command (change ownership of file/directory)
      `-- the "run as root" command; everything after this is run with root privileges

Jetez un coup d'œil à cette question pour savoir pourquoi, dans de nombreuses situations, ce n'est pas une bonne idée d'utiliser des backticks.

Au fait, si vous avez toujours voulu utiliser un backtick littéralement, par exemple dans une chaîne, vous pouvez y échapper en plaçant une barre oblique inverse ( \) avant celle-ci.

rozcietrzewiacz
la source
36
Cela explique assez bien les backticks, mais utiliser $(your expression)est un meilleur moyen de faire la même chose car il $()vous permet d'imbriquer des expressions. par exemple: vous cd $(dirname $(type -P touch))mettra dans le répertoire contenant la touchcommande
Khaja Minhajuddin
11
@KhajaMinhajuddin Vous avez certainement raison en matière d'imbrication - la question mentionnée ci-dessus la couvre en détail. Mais même si j’estime que c’est une bonne pratique à utiliser $()dans la plupart des situations, cela ne rend pas les backtick plus pires . Pour des raisons pratiques, il faut bien admettre qu’ils taperont beaucoup plus rapidement sur la ligne de commande (2 frappes au clavier contre au moins 5, y compris Shift).
rozcietrzewiacz
2
@rozcietrzewiacz Votre dernière remarque vaut probablement pour la plupart des claviers, mais elle $( )est certainement plus facile à taper qu'au ` `moins sur un clavier français.
Juillet
1
@KhajaMinhajuddin Vous pouvez imbriquer des backticks, mais vous devez vous échapper du 2e niveau des backticks et vous devez disposer de 3 backticks, au 3ème niveau, de 5 backticks, du 4e niveau 7, etc.
JustinCB
66

Je voudrais ajouter quelques points supplémentaires ici.

Le backtick `…`est en fait appelé substitution de commande . Le but de la substitution de commande est d’évaluer la commande qui est placée à l’intérieur du backtick et de fournir son résultat en tant qu’argument à la commande réelle.

La substitution de commande peut être effectuée de deux manières, l’une $(…)et l’autre `…`. Les deux fonctionnent de la même façon, mais la $(…)forme est moderne et offre plus de clarté et de lisibilité.

Et donc

sudo chown $(id -u) /somedir

peut être préféré à l'autre.

Et une autre chose que vous devez noter ici est la relation de substitution de commande avec les règles de citations bash mentionnées dans le document bash .

Si la substitution apparaît entre guillemets, le fractionnement des mots et le développement du nom de fichier ne sont pas effectués sur les résultats.

Kannan Mohan
la source
8
Aussi, $(...)nidifie mieux.
Kusalananda
$()et "``"ne fonctionne pas de la même façon
Kun
10

Une note de clarification rarement couverte:

Les crapauds (parfois aussi appelés tombes car ils constituent un accent commun en français et dans d’autres langues) ne remplacent que la sortie standard , mais pas l’erreur standard.

Donc, pour continuer l'exemple précédent:

file `which hostname`

fonctionnera comme prévu, mais en:

file `which hostnameX`

whichretournera une erreur et cette sortie passera à l'erreur standard, plutôt que de se substituer à la ligne de commande à côté de file; il n'y aura pas de sortie standard du tout, ce que vous pouvez confirmer en lançant:

which hostnameX

which hostnameX 2>/dev/null

Dans ce cas,

file `which hostnameX` 

produira deux messages d'erreur (le premier, en raison de which hostnameXet le second juste après le premier, en raison du fichier lui-même, qui détecte que le nom du fichier est manquant et ainsi, la commande entière

réduira essentiellement à seulement:

file

ce qui, bien sûr, est un mauvais usage, et retournera une erreur d'utilisation.

(Si vous voulez vérifier par vous-même, vous pouvez essayer:

file `which hostnameX 2>/dev/null`    # just the file-command bad-usage error msg is printed

file `which hostnameX 2>/dev/null` 2>/dev/null  # now nothing is printed on the screen :)
Dave K
la source
4

Le backtick `exécute le contenu de la chaîne incluse, donc quelque chose comme ceci

file `which hostname`

va trouver le chemin d'accès à la commande hostname, puis vous dire comment elle a été construite.

La commande que vous avez insérée dans votre question est id -uexécutée pour obtenir l'ID utilisateur effectif, puis modifie la propriété de / somedir en cet utilisateur.

julien
la source
2

Ce symbole signifie que tout ce qu'il contient est interprété comme le résultat de cette commande.

par exemple:

$ls /home
one two
$pwd
/usr/three
$cp `pwd` /home
$ls /home
one two three

Les résultats ci-dessus dans le threerépertoire en cours de copie dans mon /homerépertoire.

Hanan N.
la source
1

Les backticks ressemblent à la substitution de commande. Cette syntaxe est archaïque accents graves, et connaît le signe dollar avec deux parenthèses est commune: $().

Qu'est-ce que la substitution de commande?

La substitution de commande est une opération unique avec une syntaxe dédiée permettant à la fois d’exécuter une commande et de stocker sa sortie dans une variable pour une utilisation ultérieure.

Un exemple avec date:

thedate=$(date)

Nous pourrions alors imprimer le résultat: 'La date est% s \ n' "$ thedate" `.

  1. La syntaxe de substitution de commande est $().
  2. La commande elle-même est date.
  3. En combinant les deux, on obtient $(date)la sortie qui correspond à la substitution.
  4. Nous affichons la valeur de sortie maintenue par la variable avec printf, par la commande ci-dessus.
utilisateur9303970
la source