GNU/Linux >> Tutoriels Linux >  >> Linux

Que signifie ${1+"[email protected]"} dans un script shell, et en quoi diffère-t-il de "[email protected]" ?

Dans la documentation Perl, perlrun(1) suggère de lancer des scripts Perl à l'aide d'un en-tête bilingue shell/Perl :

#!/bin/sh
#! -*-perl-*-
eval 'exec perl -x -wS $0 ${1+"[email protected]"}'
    if 0;

Que signifie ${1+"[email protected]"} moyenne? J'ai essayé d'utiliser "[email protected]" à la place (en utilisant Bash comme /bin/sh), et cela semble fonctionner aussi bien.

Modifier

Deux réponses ci-dessous indiquent qu'il est censé être ${1:+"[email protected]"} . Je connais le ${parameter:+word} (« Use Alternate Value ») syntaxe documentée dans bash(1). Cependant, je ne suis pas convaincu, car

  1. Les deux ${1+"[email protected]"} et "[email protected]" fonctionnent très bien, même s'il n'y a pas de paramètres. Si je crée simple.sh comme

    #!/bin/sh
    eval 'exec /usr/bin/perl -x -S -- $0 "[email protected]"'
        if 0;
    #!perl
    use Data::Dumper;
    print Dumper(\@ARGV);
    

    et question.sh comme

    #!/bin/sh
    eval 'exec /usr/bin/perl -x -S -- $0 ${1+"[email protected]"}'
        if 0;
    #!perl
    use Data::Dumper;
    print Dumper(\@ARGV);
    

    Je peux faire fonctionner les deux de manière identique :

    $ ./question.sh 
    $VAR1 = [];
    $ ./question.sh a
    $VAR1 = [
              'a'
            ];
    $ ./question.sh a 'b c'
    $VAR1 = [
              'a',
              'b c'
            ];
    $ ./question.sh ""
    $VAR1 = [
              ''
            ];
    $ ./simple.sh 
    $VAR1 = [];
    $ ./simple.sh a
    $VAR1 = [
              'a'
            ];
    $ ./simple.sh a 'b c'
    $VAR1 = [
              'a',
              'b c'
            ];
    $ ./simple.sh ""
    $VAR1 = [
              ''
            ];
    
  2. D'autres sources sur Internet utilisent également ${1+"[email protected]"} , dont un hacker qui semble savoir ce qu'il fait.

Peut-être ${parameter+word} est une syntaxe alternative non documentée (ou obsolète) pour ${parameter:+word} ? Quelqu'un pourrait-il confirmer cette hypothèse ?

Réponse acceptée :

C'est pour la compatibilité avec le shell Bourne. Le shell Bourne était un ancien shell qui a été publié pour la première fois avec la version 7 d'Unix en 1979 et était encore courant jusqu'au milieu des années 90 sous le nom de /bin/sh sur la plupart des Unix commerciaux.

C'est l'ancêtre de la plupart des coquillages de type Bourne comme ksh , bash ou zsh .

Il avait quelques fonctionnalités gênantes dont beaucoup ont été corrigées dans ksh et les autres shells et la nouvelle spécification standard de sh , dont l'un est celui-ci :

Avec le shell Bourne (au moins les variantes où il n'a pas été corrigé) :"[email protected]" se développe en un argument vide si la liste des paramètres positionnels est vide ($# == 0 ) au lieu de pas d'argument du tout.

${var+something} se développe en "quelque chose" sauf si $var n'est pas défini. Il est clairement documenté dans tous les shells mais difficile à trouver dans le bash documentation car vous devez faire attention à cette phrase :

Lorsque vous n'effectuez pas d'expansion de sous-chaîne, à l'aide des formulaires documentés ci-dessous, bash teste un paramètre non défini ou nul. L'omission des deux-points entraîne un test uniquement pour un paramètre non défini .

Alors ${1+"[email protected]"} se développe en "[email protected]" uniquement si $1 est défini ($# > 0 ) qui contourne cette limitation du shell Bourne.

En relation:Différence entre EOT et EOF?

Notez que le shell Bourne est le seul shell avec ce problème. sh moderne s (c'est-à-dire sh conforme à la spécification POSIX de sh (ce que le shell Bourne n'est pas)) n'ont pas ce problème. Vous n'en avez donc besoin que si vous avez besoin que votre code fonctionne sur de très anciens systèmes où /bin/sh peut être un shell Bourne au lieu d'un shell standard (notez que POSIX ne spécifie pas l'emplacement du sh standard , donc par exemple sur Solaris avant Solaris 11, /bin/sh était toujours un shell Bourne (mais n'avait pas ce problème particulier) tandis que le sh normal/standard était à un autre endroit (/usr/xpg4/bin/sh )).

Il y a un problème dans ce perlrun page perldoc dans ce $0 n'est pas cité cependant.

Voir http://www.in-ulm.de/~mascheck/various/bourne_args/ pour plus d'informations.


Linux
  1. Qu'est-ce qu'un Makefile et comment ça marche ?

  2. Comment comparer des nombres et des chaînes dans le script shell Linux

  3. Qu'est-ce qu'un serveur Web et comment fonctionne un serveur Web ?

  4. Que signifie `:-` dans un script shell ?

  5. Qu'est-ce que Podman et en quoi diffère-t-il de Docker ?

Commande de fichier Linux :que fait-elle et comment l'utiliser

Qu'est-ce que null signifie dans Linux et l'informatique

Qu'est-ce que cela signifie d'être "compatible sh" ?

Comment créer et exécuter un script shell dans Ubuntu 22.04

Que sont les scripts shell ? Comment créer des scripts shell ?

Que signifie la syntaxe |&en langage shell ?