web-dev-qa-db-fra.com

Les backticks (c'est-à-dire `cmd`) dans les shells * sont-ils déconseillés?

J'ai vu ce commentaire plusieurs fois sur Unix & Linux ainsi que sur d'autres sites qui utilisent le phrasé "les backticks ont été dépréciés", en ce qui concerne les shells tels que Bash & Zsh.

Cette déclaration est vraie ou fausse?

126
slm

Il existe deux significations différentes de "obsolète".

être déconseillé: (principalement d'une fonctionnalité logicielle) être utilisable mais considéré comme obsolète et mieux évité, généralement en raison d'avoir été remplacé.

—Nouveau dictionnaire américain d'Oxford

Selon cette définition, les backticks sont déconseillés.

Le statut obsolète peut également indiquer que la fonctionnalité sera supprimée à l'avenir.

Wikipedia

Selon cette définition, les backticks sont pas déconseillés.

Toujours pris en charge:

En citant Open Group Specification on Shell Command Languages , en particulier la section "2.6.3 Substitution de commandes", on peut voir que les deux formes de substitution de commandes, les astuces (`..cmd..`) Ou les dollars parens ($(..cmd..)) sont toujours pris en charge dans la mesure où la spécification va.

extrait

La substitution de commande permet de remplacer la sortie d'une commande à la place du nom de la commande elle-même. La substitution de commande doit se produire lorsque la commande est incluse comme suit:

          $(command)

          or (backquoted version):

          `command`

Le shell doit étendre la substitution de commande en exécutant la commande dans un environnement de sous-shell (voir Environnement d'exécution Shell) et en remplaçant la substitution de commande (le texte de la commande plus la $() ou les guillemets) englobants par la sortie standard de la commande , en supprimant les séquences d'un ou plusieurs caractères <newline> à la fin de la substitution. Les caractères <newline> intégrés avant la fin de la sortie ne doivent pas être supprimés; cependant, ils peuvent être traités comme des délimiteurs de champ et éliminés lors de la division du champ, en fonction de la valeur de l'IFS et de la cotation en vigueur. Si la sortie contient des octets nuls, le comportement n'est pas spécifié.

Dans le style de substitution de commandes entre guillemets, <backslash> doit conserver sa signification littérale, sauf lorsqu'il est suivi de: '$', '\`' Ou < barre oblique inversée>. La recherche de la citation inverse correspondante doit être satisfaite par la première citation inverse non échappée; au cours de cette recherche, si une citation inverse non échappée est rencontrée dans un commentaire Shell, un document ici, une substitution de commande incorporée du formulaire $(command) ou une chaîne entre guillemets, des résultats indéfinis se produisent. Une chaîne entre guillemets simples ou doubles qui commence, mais ne se termine pas, dans la séquence "`...`" Produit des résultats non définis.

Avec le formulaire $(command), tous les caractères suivant la parenthèse ouvrante à la parenthèse fermante correspondante constituent la commande. Tout script Shell valide peut être utilisé pour la commande, à l'exception d'un script composé uniquement de redirection qui produit des résultats non spécifiés.

Alors, pourquoi tout le monde dit que les contre-coups sont dépréciés?

Parce que la plupart des cas d'utilisation devrait utiliser le formulaire de parens dollar au lieu de backticks. (Obsolète dans le premier sens ci-dessus.) La plupart des sites les plus réputés (y compris U&L) l'indiquent souvent également, ce sont donc de bons conseils. Ce conseil ne doit pas être confondu avec un plan inexistant pour supprimer le support des backticks des coquilles.

  • BashFAQ # 082 - Pourquoi $ (...) est-il préféré à `...` (backticks)?

    extrait

    `...` Est la syntaxe héritée requise uniquement par le plus ancien des bourne-shells non compatibles POSIX. Il y a plusieurs raisons de toujours préférer la syntaxe $(...):

    ...

  • Wiki Bash Hackers - Syntaxe obsolète et obsolète

    extrait

    Il s'agit de l'ancienne forme compatible Bourne de la substitution de commande . Les syntaxes `COMMANDS` Et $(COMMANDS) sont toutes deux spécifiées par POSIX, mais la seconde est préférée grandement, bien que la première soit malheureusement encore très répandue dans les scripts. Les substitutions de commandes de nouveau style sont largement implémentées par tous les Shell modernes (puis certains). La seule raison d'utiliser des backticks est la compatibilité avec un vrai Bourne Shell (comme Heirloom). Les substitutions de commandes Backtick nécessitent un échappement spécial lorsqu'elles sont imbriquées, et les exemples trouvés dans la nature sont souvent mal cités. Voir: Pourquoi $ (...) est-il préféré à `...` (backticks)? .

  • justification standard POSIX

    extrait

    En raison de ces comportements incohérents, la variété de substitution de commandes entre guillemets n'est pas recommandée pour les nouvelles applications qui imbriquent des substitutions de commandes ou tentent d'incorporer des scripts complexes.

REMARQUE: Ce troisième extrait (ci-dessus) montre plusieurs situations où les astuces ne fonctionnent tout simplement pas, mais la nouvelle méthode dollar parens le fait, en commençant par le paragraphe suivant:

De plus, la syntaxe rétrogradée a des restrictions historiques sur le contenu de la commande incorporée. Alors que le nouveau formulaire "$ ()" peut traiter tout type de script incorporé valide, le formulaire avec guillemet arrière ne peut pas gérer certains scripts valides qui incluent des guillemets.

Si vous continuez à lire cette section, les échecs sont mis en évidence, montrant comment ils échoueraient à l'aide de backticks, mais fonctionnent en utilisant la notation de parens dollar plus récente.

Conclusions

Il est donc préférable que vous utilisiez des parens en dollars plutôt que des contre-coups, mais vous n'utilisez pas réellement quelque chose qui est techniquement "obsolète" comme dans "cela cessera de fonctionner entièrement à un moment prévu".

Après avoir lu tout cela, vous devriez avoir la conclusion que vous êtes fortement encouragé à utiliser des parens dollar sauf si vous spécifiquement avez besoin de compatibilité avec un véritable shell Bourne non POSIX original.

131
slm

Ce n'est pas obsolète, mais les astuces (`...`) 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 barres obliques inverses (\) À l'intérieur des backticks sont gérées de manière non évidente:

    $ echo "`echo \\a`" "$(echo \\a)"
    a \a
    $ echo "`echo \\\\a`" "$(echo \\\\a)"
    \a \\a
    # Note that this is true for *single quotes* too!
    $ foo=`echo '\\'`; bar=$(echo '\\'); echo "foo is $foo, bar is $bar" 
    foo is \, bar is \\
    
  • Les citations imbriquées à l'intérieur de $() sont beaucoup plus pratiques:

    echo "x is $(sed ... <<<"$y")"
    

    au lieu de:

    echo "x is `sed ... <<<\"$y\"`"
    

    ou écrire quelque chose comme:

    IPs_inna_string=`awk "/\`cat /etc/myname\`/"'{print $1}' /etc/hosts`
    

    parce que $() utilise un tout nouveau contexte pour citer

    ce qui n'est pas portable car les shells Bourne et Korn nécessiteraient ces contre-obliques, contrairement à Bash et dash.

  • La syntaxe de substitution des commandes d'imbrication est plus simple:

    x=$(grep "$(dirname "$path")" file)
    

    que:

    x=`grep "\`dirname \"$path\"\`" file`
    

    parce que $() applique un tout nouveau contexte pour les citations, donc chaque substitution de commande est protégée et peut être traitée seule sans souci particulier de la citation et de l'échappement. Lorsque vous utilisez des backticks, il devient plus laid et plus laid après deux niveaux et plus.

    Quelques exemples supplémentaires:

    echo `echo `ls``      # INCORRECT
    echo `echo \`ls\``    # CORRECT
    echo $(echo $(ls))    # CORRECT
    
  • Il résout un problème de comportement incohérent lors de l'utilisation de backquotes:

    • echo '\$x' Affiche \$x
    • echo `echo '\$x'` Affiche $x
    • echo $(echo '\$x') affiche \$x
  • La syntaxe des raccourcis a des restrictions historiques sur le contenu de la commande incorporée et ne peut pas gérer certains scripts valides qui incluent des guillemets, tandis que le nouveau formulaire $() peut traiter tout type de script incorporé valide.

    Par exemple, ces scripts intégrés par ailleurs valides ne fonctionnent pas dans la colonne de gauche, mais fonctionnent à droite IEEE :

    echo `                         echo $(
    cat <<\eof                     cat <<\eof
    a here-doc with `              a here-doc with )
    eof                            eof
    `                              )
    
    
    echo `                         echo $(
    echo abc # a comment with `    echo abc # a comment with )
    `                              )
    
    
    echo `                         echo $(
    echo '`'                       echo ')'
    `                              )
    

Par conséquent, la syntaxe pour $ - préfixée substitution de commande 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 emboîtable et intuitive, sa l'analyse interne est distincte, et elle est également plus cohérente (avec toutes les autres extensions qui sont analysées à partir de guillemets doubles) 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, surtout avec des polices petites ou inhabituelles.

Source: Pourquoi $(...) est-il préféré à `...` (Backticks)? chez BashFAQ

Voir également:

16
kenorb