Übergeben von Variablen an ein Bash-Skript, wenn es bezogen wird

18

Angenommen, ich habe in main.sh:

$NAME="a string"
if [ -f $HOME/install.sh ]
    . $HOME/install.sh $NAME
fi

und in install.sh:

echo $1

Dies soll widerhallen "a string", aber es hallt nichts wider. Warum?

Jemand verwendet Sie immer noch MS-DOS
quelle
2
Bitte aktualisieren Sie die Frage nicht. Auf diese Weise können wir nicht sehen, was mit Ihrer Ausgangsfrage falsch war. Ich habe es gerade zurückgerollt.
Valentin Bajrami

Antworten:

20

Michael Mrozek deckt die meisten Probleme ab und seine Korrekturen werden funktionieren, da Sie Bash verwenden.

Möglicherweise interessiert Sie die Tatsache, dass die Möglichkeit, ein Skript mit Argumenten zu versehen, ein Bashismus ist. In shoder dashIhr main.shwird nichts zurückmelden, da die Argumente für das Quellenskript ignoriert werden und $1auf das Argument für verweisenmain.sh.

Wenn Sie das Skript shals Quelle angeben, haben Sie den Eindruck, Sie hätten den Text des Skripts einfach kopiert und in die Datei eingefügt, aus der es stammt. Beachten Sie Folgendes (Anmerkung, ich habe die von Michael empfohlene Korrektur vorgenommen):

$ bash ./test.sh
A String
$ sh ./test.sh

$ sh ./test.sh "HELLO WORLD"
HELLO WORLD
Steven D
quelle
"In sh oder dash wird Ihre main.sh nichts wiedergeben, da die Argumente für das Quellenskript ignoriert werden und $ 1 auf das Argument für main.sh verweist." Genau das passiert. Danke für die Antwort.
Jemand benutzt Sie immer noch MS-DOS
Ich habe Ihre Antwort als akzeptiert markiert, weil das eigentliche Problem nicht darin bestand, dass mein Skript fehlerhaft war, sondern hauptsächlich, weil ich sh mit bash gleichgesetzt habe und bash es in dieser Situation nicht gut macht, sh zu emulieren. Ihre Antwort hat mich über dieses Problem aufgeklärt, danke;
Jemand verwendet Sie immer noch MS-DOS
2
Technisch gesehen ist es hier eher ein Kshism (bereits in Ksh86 vorhanden, wahrscheinlich früher). @ SomebodystillusesyouMS-DOS, die "sh" -Spezifikation sagt nicht aus, was passieren soll, wenn Sie zusätzliche Argumente übergeben, sodass das Bindestrich- oder Bash-Verhalten nicht mehr "sh" ist als das andere und gleichermaßen gültig.
Stéphane Chazelas
16

Ich sehe drei Fehler:

  1. Ihre Zuweisungszeile ist falsch:

    $NAME="a string"

    Wenn Sie einer Variablen zuweisen, wird das $; es sollte sein:

    NAME="a string"
  2. Du wirst vermisst then; Die bedingte Linie sollte sein:

    if [ -f $HOME/install.sh ]; then
  3. Sie zitieren nicht $NAME, obwohl es Leerzeichen gibt. Die Quellzeile sollte sein:

    . $HOME/install.sh "$NAME"
Michael Mrozek
quelle
Er hat auch ein paar andere Fehler, aber ich denke nicht, dass dies unbedingt die Ursache des von ihm angesprochenen Problems ist.
Steven D
@Steven Du hast recht, es gab noch ein paar, die ich nicht erwähnt habe; Es funktioniert für mich mit den Korrekturen, die ich jetzt aufgeführt habe
Michael Mrozek
@Steven Als ich das Skript zusammenstellte, um es auszuprobieren, habe ich es auf abgekürzt [ -f $HOME/install.sh ] && . $HOME/install.sh $NAME. Ich sollte solche Dinge wahrscheinlich nicht tun, wenn ich nach Fehlern suche
Michael Mrozek
Es sieht so aus, als wäre das andere Problem, von dem ich dachte, es gäbe eigentlich kein Problem, da er BASH ausdrücklich erwähnt.
Steven D
5

Stellen Sie einfach Ihre Parameter ein, bevor Sie das Skript aufrufen!

main.sh

#!/bin/bash
NAME=${*:-"a string"}
if [[ -f install.sh ]];
then
    set -- $NAME ;
    . install.sh ;
fi
exit;

install.sh

#!/bin/bash
echo  " i am sourced by [ ${0##*/} ]";
echo  " with [ $@ ] as parametr(s) ";
exit;

Prüfung

u@h$ ./main.sh some args
 i am sourced by [ main.sh ]
 with [ some args ] as parametr(s) 
u@h$
Jona
quelle
Wie setzt man Flags?
Jonathan Landrum
Edit: Sie reihen sie anscheinend nur nach den --gleichen Befehlsargumenten auf:set -- -v foo -l bar -j "${bin}"
Jonathan Landrum