Passer des variables à un script bash lors de son sourcing

18

Supposons que j'aie dans main.sh:

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

et dans install.sh:

echo $1

Ceci est censé faire écho "a string", mais il ne fait écho à rien. Pourquoi?

Quelqu'un vous utilise toujours MS-DOS
la source
2
Ne mettez pas à jour la question s'il vous plaît. De cette façon, nous ne pouvons pas voir ce qui n'allait pas avec votre question initiale. Je viens de le faire reculer.
Valentin Bajrami

Réponses:

20

Michael Mrozek couvre la plupart des problèmes et ses correctifs fonctionneront puisque vous utilisez Bash.

Vous pouvez être intéressé par le fait que la possibilité de générer un script avec des arguments est un bashisme. Dans shou dashvotre main.shne fera écho à rien, car les arguments du script source sont ignorés et $1feront référence à l'argumentmain.sh.

Lorsque vous sourcez le script sh, c'est comme si vous venez de copier et coller le texte du script source dans le fichier à partir duquel il a été obtenu. Tenez compte des éléments suivants (notez que j'ai apporté la correction recommandée par Michael):

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

$ sh ./test.sh "HELLO WORLD"
HELLO WORLD
Steven D
la source
"Dans sh ou dash, votre main.sh ne fera aucun écho car les arguments du script source sont ignorés et $ 1 fera référence à l'argument de main.sh" C'est exactement ce qui se passe. Merci de répondre.
Quelqu'un vous utilise toujours MS-DOS
J'ai marqué votre réponse comme acceptée, car le vrai problème n'était pas les erreurs dans mon script, mais principalement parce que j'assimilais sh à bash, et bash émule mal sh dans cette situation. Votre réponse m'a éclairé sur ce problème, merci;
Quelqu'un vous utilise toujours MS-DOS
2
Techniquement, c'est plus un kshism ici (déjà là dans ksh86, probablement plus tôt). @ SomebodystillusesyouMS-DOS, la spécification "sh" ne dit pas ce qui devrait se produire si vous passez des arguments supplémentaires, donc le comportement du tiret ou du bash n'est pas plus "sh" que l'autre et est également valide.
Stéphane Chazelas
16

Je vois trois erreurs:

  1. Votre ligne d'affectation est incorrecte:

    $NAME="a string"

    Lorsque vous attribuez à une variable, vous n'incluez pas le $; ça devrait être:

    NAME="a string"
  2. Vous manquez then; la ligne conditionnelle doit être:

    if [ -f $HOME/install.sh ]; then
  3. Vous ne citez pas $NAME, même s'il contient des espaces. La ligne source doit être:

    . $HOME/install.sh "$NAME"
Michael Mrozek
la source
Il a également quelques autres erreurs, mais je ne pense pas que ce soit nécessairement la source du problème qu'il soulève.
Steven D
@Steven Vous avez raison, il y en avait quelques autres que je n'ai pas mentionnés; cela fonctionne pour moi avec les correctifs que j'ai énumérés maintenant
Michael Mrozek
@Steven Lorsque je jetais ensemble le script pour l'essayer, je l'ai abrégé [ -f $HOME/install.sh ] && . $HOME/install.sh $NAME; Je ne devrais probablement pas faire des choses comme ça quand je cherche des erreurs
Michael Mrozek
Il semble que l'autre problème que je pensais qu'il n'y avait en fait pas de problème puisqu'il mentionne spécifiquement BASH.
Steven D
5

définissez simplement vos paramètres avant de vous procurer le script!

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;

tester

u@h$ ./main.sh some args
 i am sourced by [ main.sh ]
 with [ some args ] as parametr(s) 
u@h$
Jonas
la source
Comment définissez-vous les drapeaux?
Jonathan Landrum
Edit: vous apparemment les enchaînez juste après --comme ils étaient des arguments de commande:set -- -v foo -l bar -j "${bin}"
Jonathan Landrum