GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Was bedeutet ${1+„[email protected]“} in einem Shell-Skript und wie unterscheidet es sich von „[email protected]“?

In der Perl-Dokumentation schlägt perlrun(1) vor, Perl-Skripte mit einem zweisprachigen Shell/Perl-Header zu starten:

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

Was bedeutet ${1+"[email protected]"} gemein? Ich habe versucht, "[email protected]" zu verwenden stattdessen (mit Bash als /bin/sh), und es scheint genauso gut zu funktionieren.

Bearbeiten

Zwei Antworten unten besagen, dass es ${1:+"[email protected]"} sein soll . Ich kenne den ${parameter:+word} („Use Alternate Value“)-Syntax, die in bash(1) dokumentiert ist. Ich bin jedoch nicht überzeugt, weil

  1. Beide ${1+"[email protected]"} und "[email protected]" funktionieren gut, auch wenn es keine Parameter gibt. Wenn ich simple.sh als

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

    und question.sh als

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

    Ich kann beide identisch zum Laufen bringen:

    $ ./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. Andere Quellen im Internet verwenden ebenfalls ${1+"[email protected]"} , darunter ein Hacker, der zu wissen scheint, was er tut.

Vielleicht ${parameter+word} ist eine undokumentierte alternative (oder veraltete) Syntax für ${parameter:+word} ? Könnte jemand diese Hypothese bestätigen?

Akzeptierte Antwort:

Das dient der Kompatibilität mit der Bourne-Shell. Die Bourne-Shell war eine alte Shell, die erstmals 1979 mit der Unix-Version 7 veröffentlicht wurde und noch bis Mitte der 90er Jahre als /bin/sh gebräuchlich war auf den meisten kommerziellen Unices.

Es ist der Vorfahre der meisten Bourne-ähnlichen Muscheln wie ksh , bash oder zsh .

Es hatte ein paar unangenehme Funktionen, von denen viele in ksh behoben wurden und die anderen Shells und die neue Standardspezifikation von sh , einer davon ist dieser:

Mit der Bourne-Shell (zumindest die Varianten, bei denen es nicht behoben wurde):"[email protected]" wird zu einem leeren Argument erweitert, wenn die Liste der Positionsparameter leer ist ($# == 0 ) statt gar kein Argument.

${var+something} erweitert sich zu „etwas“, es sei denn $var ist ungesetzt. Es ist in allen Shells klar dokumentiert, aber in der bash schwer zu finden Dokumentation, da Sie auf diesen Satz achten müssen:

Wenn keine Substring-Erweiterung durchgeführt wird, testet bash mithilfe der unten dokumentierten Formulare auf einen Parameter, der nicht gesetzt oder null ist. Das Weglassen des Doppelpunkts führt zu einem Test nur für einen Parameter, der nicht gesetzt ist .

Also ${1+"[email protected]"} erweitert sich zu "[email protected]" nur wenn $1 gesetzt ist ($# > 0 ), die diese Einschränkung der Bourne-Shell umgeht.

Verwandte:Unterschied zwischen EOT und EOF?

Beachten Sie, dass die Bourne-Shell die einzige Shell mit diesem Problem ist. Modernes sh s (das ist sh entspricht der POSIX-Spezifikation von sh (was die Bourne-Shell nicht ist)) haben dieses Problem nicht. Sie brauchen das also nur, wenn Ihr Code auf sehr alten Systemen funktionieren soll, auf denen /bin/sh könnte eine Bourne-Shell anstelle einer Standard-Shell sein (beachten Sie, dass POSIX den Ort des Standard-sh nicht angibt , also zum Beispiel auf Solaris vor Solaris 11, /bin/sh war immer noch eine Bourne-Shell (obwohl dieses spezielle Problem nicht auftrat), während das normale/Standard-sh war an einem anderen Ort (/usr/xpg4/bin/sh )).

Es gibt ein Problem in diesem perlrun perldoc-Seite in diesem $0 wird allerdings nicht zitiert.

Weitere Informationen finden Sie unter http://www.in-ulm.de/~mascheck/various/bourne_args/.


Linux
  1. So vergleichen Sie Zahlen und Zeichenfolgen im Linux-Shell-Skript

  2. Was ist ein Webserver und wie funktioniert ein Webserver?

  3. Was bedeuten -s und [[]] in einer if-Bedingung in Bash?

  4. Was ist Podman und wie unterscheidet es sich von Docker?

  5. Was ist DNS und wie funktioniert es?

Linux-Dateibefehl:Was macht er und wie wird er verwendet?

Was bedeutet null in Linux und Computing

Was bedeutet es, „sh-kompatibel“ zu sein?

So erstellen und führen Sie ein Shell-Skript in Ubuntu 22.04 aus

Was bedeutet set -e in einem Bash-Skript?

Was bedeutet die Syntax |&in der Shell-Sprache?