shell
  • whitespace
  • 2017-03-11 4 views 3 likes 
    3
    $ freebsd-version 
    10.3-RELEASE-p17 
    $ 
    
    portinstall() { 
        port="$1"; shift 
        env="[email protected]" 
    
        #1 
        env "[email protected]" printenv | grep -E '^WITH(OUT)?=' 
        #2 
        env "$env" printenv | grep -E '^WITH(OUT)?=' 
        #3 
        env "$*" printenv | grep -E '^WITH(OUT)?=' 
        #4 
        env [email protected] printenv | grep -E '^WITH(OUT)?=' 
        #5 
        env $* printenv | grep -E '^WITH(OUT)?=' 
    
    } 
    
    
    portinstall foo/bar WITH='baz xyzzy' WITHOUT='quux' 
    

    Nur 1 Werke #, dessen Ausgang:Bourne-Shell Leerzeichen Feinheiten

    WITHOUT=quux 
    WITH=baz xyzzy 
    

    Mit # 2, # 3 (MIT ist nur eine Variable "baz xyzzy OHNE = quux"):

    WITH=baz xyzzy WITHOUT=quux 
    

    Mit # 4, # 5

    env: xyzzy: No such file or directory 
    

    Meine Hauptfrage ist, warum # 1 funktioniert, aber das scheinbar gleichwertige # 2 nicht?

    +0

    Das Problem mit 'env $ @ printenv' fehlt doppelte Anführungszeichen,' env' läuft mit mehreren Argumenten (mehr als eins), die es nicht mag, daher der Fehler, Double-quoting sollte es beheben! – Inian

    +0

    @Inian, yup, # 4-5 sind ziemlich selbsterklärend, ich habe sie der Vollständigkeit halber aufgelistet. Meine Verwirrung ist mit # 1-2. – Rihad

    Antwort

    2

    Die Verwendung von "[email protected]" ist meistens korrekt, aber vielleicht hilft diese Analyse Ihnen zu verstehen, warum.

    Ihr Code ist ungefähr:

    env="[email protected]" 
    
    #1 
    env "[email protected]" printenv | grep -E '^WITH(OUT)?=' 
    #2 
    env "$env" printenv | grep -E '^WITH(OUT)?=' 
    #3 
    env "$*" printenv | grep -E '^WITH(OUT)?=' 
    #4 
    env [email protected] printenv | grep -E '^WITH(OUT)?=' 
    #5 
    env $* printenv | grep -E '^WITH(OUT)?=' 
    

    und Sie Aufruf das Skript mit Argumenten WITH='baz xyzzy' WITHOUT='quux'. Ja, Sie haben eine Funktion und ein Ersatzargument als $1 hinzufügen, um die Komplexität, aber sie sind meist irrelevant; Das ist der Kern.

    Im Allgemeinen bildet $* die Wörter in den durch Leerzeichen getrennten Argumenten ab; [email protected] macht das gleiche. Wenn sie in doppelte Anführungszeichen eingeschlossen sind, verhalten sie sich unterschiedlich: "[email protected]" wird auf die Menge von Argumenten erweitert, die interne Leerzeichen erhalten, während "$*" auf eine einzelne Zeichenfolge mit internen Leerzeichen und einem einzigen Leerzeichen zwischen Argumenten abgebildet wird.

    Im Kontext von env="[email protected]" verhält sich die Zuweisung jedoch wie env="$*" - Sie erhalten einen einzelnen String in der Variablen. Um die einzelnen Argumente in Bash zu erhalten, würden Sie ein Array verwenden:

    env=("[email protected]") 
    

    und man konnte drucken Sie sie mit:

    printf '%s\n' "${env[@]}" 
    

    Allerdings, das ist weg an einer Tangente.

    Mit # 1 enden Sie mit einem Aufruf von env mit zwei gültigen, Platz-Erhaltung Zuweisungen, die printenv ordnungsgemäß druckt und grep Filter, geben Sie die zwei Variablenwerte. Aus diesem Grund ist "[email protected]" normalerweise korrekt.

    mit # 2 und # 3, am Ende mit einem Aufruf von env mit einer einzigen Saite bis die WITH= beginnt (also auf die Variable WITH zuweist, und der Rest der Zeichenfolge ist baz xyzzy WITHOUT=quux, weshalb Sie sehen, dass ..

    env WITH=baz xyzzy WITHOUT=quux printenv 
    

    da xyzzy ist keine Zuordnung: als Ausgang Es gibt eine einzige Umgebungsvariable - - MIT aber ihr Wert Leerzeichen enthält und einen Auftrag

    Mit # 4 und # 5, haben Sie laufen Es wird als Befehl behandelt, der mit a aufgerufen werden soll rguments WITHOUT=quux und printenv (und mit WITH=baz hinzugefügt, um die Umgebung), aber Sie haben kein Programm namens xyzzy auf Ihrem Pfad, so env gibt Ihnen den Fehler.Sie könnten ein Programm xyzzy erstellen, um zu zeigen, was passiert.

    Mit dem Array env, könnten Sie laufen:

    env "${env[@]}" printenv | … 
    

    und Sie würden das gleiche Ergebnis wie # 1 erhalten.

    +0

    Gut gelesen: http://unix.stackexchange.com/questions/41571/what-is-the-difference-between-and – codeforester

    +0

    Vielen Dank für eine sehr detaillierte Erklärung! – Rihad

    Verwandte Themen