Il existe deux façons de capturer la sortie de la ligne de commande dans bash
:
Anciens backticks du shell Bourne
``
:var=`command`
$()
syntaxe (qui, pour autant que je sache, est spécifique à Bash, ou du moins n'est pas prise en charge par les anciens shells non POSIX comme Bourne d'origine)var=$(command)
Y a-t-il un avantage à utiliser la deuxième syntaxe par rapport aux backticks? Ou les deux sont-ils totalement équivalents à 100%?
$()
est POSIX et supporté par tous les shells Bourne modernes, par exemple ksh, bash, ash, dash, zsh, busybox, vous l'appelez. (Un pas si moderne est Solaris/bin/sh
, mais sur Solaris, vous vous assurez d'utiliser le moderne à la/usr/xpg4/bin/sh
place).$()
et les backticks dans les alias. Si vous avezalias foo=$(command)
dans votre.bashrc
alorscommand
sera exécuté lorsque la commande d'alias elle-même sera exécutée pendant l'.bashrc
interprétation. Avecalias foo=`command`
,command
sera exécuté à chaque exécution de l'alias. Mais si vous échappez au$
avec le$()
formulaire (par exemplealias foo=\$(command)
), il s'exécutera également à chaque fois que l'alias est exécuté, au lieu de lors de l'.bashrc
interprétation. Autant que je sache en testant, de toute façon; Je ne trouve rien dans la documentation bash qui explique ce comportement.`command`
command
n'est exécuté qu'une seule fois. Je l'ai vérifié: function aaa () {printf date; echo aaa >> ~ / test.txt; } alias test1 =aaa
. La fonction aaa n'est exécutée qu'une seule fois (après chaque connexion) quel que soit le nombre d'test1
exécutions d' alias ( ). J'ai utilisé .bashrc (sur Debian 10).Réponses:
Le principal est la possibilité de les imbriquer , des commandes dans des commandes, sans perdre la raison en essayant de déterminer si une forme d'échappée fonctionnera sur les backticks.
Un exemple, quoique quelque peu artificiel:
qui vous donnera une liste de tous les fichiers dans l'
/dir
arborescence de répertoires qui ont le même nom que le premier fichier texte daté de décembre 2011 (a) .Un autre exemple serait quelque chose comme obtenir le nom (pas le chemin complet) du répertoire parent:
(a) Maintenant que cette commande spécifique peut ne pas fonctionner réellement, je n'ai pas testé la fonctionnalité. Donc, si vous me rejetez pour cela, vous avez perdu de vue l'intention :-) Il s'agit simplement d'une illustration de la façon dont vous pouvez imbriquer, pas comme un extrait de code prêt pour la production sans bogue.
la source
Do whatever the heck you want with it.
" :-) En tout cas, je suis à peu près certain que c'était de l'humour de DVK.Supposons que vous souhaitiez trouver le répertoire lib correspondant à l'emplacement d'
gcc
installation. Tu as le choix:Le premier est plus facile que le second - utilisez le premier.
la source
x=$(f); x=`f`
se comportent de la même manière quex="$(f)"; x="`f`"
. En revanche, l' attribution de tableau n'effectuer le fractionnement à caractères comme prévu lors de l' appel des commandes. C'est pratique ( n'a pas de sens) mais incohérent.x=($(f)); x=(`f`)
$IFS
x=1 2 3 4
x=$(f)
travail sans guillemets. J'aurais dû être plus précis; Je proposais d'utiliserlibdir=$(dirname "$(dirname "$(which gcc)")")/lib
(des guillemets autour des substitutions de commandes internes ). Si vous ne les laissez pas entre guillemets, vous êtes toujours soumis à la division habituelle des mots et à l'expansion globale.Le backticks (
`...`
) est la syntaxe héritée requise uniquement par le plus ancien des bourne-shells non compatibles$(...)
POSIX et est POSIX et plus préféré pour plusieurs raisons:Les backslashes (
\
) à l'intérieur des backticks sont gérés de manière non évidente:Les citations imbriquées à l'intérieur
$()
sont beaucoup plus pratiques:au lieu de:
ou écrire quelque chose comme:
car
$()
utilise un contexte entièrement nouveau pour citerce qui n'est pas portable car les shells Bourne et Korn auraient besoin de ces barres obliques inverses, contrairement à Bash et dash.
La syntaxe des substitutions de commandes d'imbrication est plus simple:
que:
car
$()
applique un contexte entièrement nouveau pour les guillemets, de sorte que chaque substitution de commande est protégée et peut être traitée seule sans souci particulier pour les guillemets et les échappements. Lorsque vous utilisez des backticks, cela devient plus laid et plus laid après deux niveaux et plus.Quelques exemples supplémentaires:
Il résout un problème de comportement incohérent lors de l'utilisation de backquotes:
echo '\$x'
les sorties\$x
echo `echo '\$x'`
les sorties$x
echo $(echo '\$x')
les sorties\$x
La syntaxe des backticks a des restrictions historiques sur le contenu de la commande intégrée et ne peut pas gérer certains scripts valides qui incluent des backquotes, tandis que le nouveau
$()
formulaire peut traiter tout type de script intégré valide.Par exemple, ces scripts intégrés valides ne fonctionnent pas dans la colonne de gauche, mais fonctionnent sur l' IEEE de droite :
Par conséquent, la syntaxe pour la substitution de commande
$
-prefixed devrait être la méthode préférée, car elle est visuellement claire avec une syntaxe propre (améliore la lisibilité humaine et machine), elle est imbriquée et intuitive, son analyse interne est séparée et elle est également plus cohérente (avec toutes les autres extensions qui sont analysées entre guillemets) où les backticks sont la seule exception et le caractère est facilement camouflé lorsqu'il est adjacent, ce qui le rend encore plus difficile à lire, en particulier avec des polices petites ou inhabituelles.`
"
Source: Pourquoi est-il
$(...)
préférable aux`...`
(backticks)? chez BashFAQVoir également:
la source
De man bash:
la source
En plus des autres réponses,
se démarque visuellement mieux que
Les backticks ressemblent trop à des apostrophes; cela varie en fonction de la police que vous utilisez.
(Et, comme je viens de le remarquer, les backticks sont beaucoup plus difficiles à saisir dans les échantillons de code en ligne.)
la source
$
(
et)
que pour le backtick; YMMV.$()
permet l'imbrication.Je pense que les backticks ne le permettent pas.
la source
out=`echo today is \`date\``
.C'est le standard POSIX qui définit la
$(command)
forme de substitution de commande. La plupart des shells utilisés aujourd'hui sont compatibles POSIX et prennent en charge cette forme préférée par rapport à la notation archaïque backtick. La section de substitution de commande (2.6.3) du document Shell Language décrit ceci:la source
C'est une question héritée, mais je suis venu avec un exemple parfaitement valable de
$(...)
over`...`
.J'utilisais un bureau à distance pour Windows exécutant cygwin et je voulais itérer sur le résultat d'une commande. Malheureusement, le caractère backtick était impossible à saisir, soit à cause du bureau à distance, soit de cygwin lui-même.
Il est raisonnable de supposer qu'un signe dollar et des parenthèses seront plus faciles à saisir dans des configurations aussi étranges.
la source