Passando variáveis ​​para um script bash ao fornecê-lo


18

Suponha que eu tenha no main.sh:

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

e no install.sh:

echo $1

Isso deveria ecoar "a string", mas não ecoa nada. Por quê?


2
Não atualize a pergunta, por favor. Dessa forma, não podemos ver o que estava errado com sua pergunta inicial. Eu apenas rolei de volta.
Valentin Bajrami

Respostas:


20

Michael Mrozek cobre a maioria dos problemas e suas correções funcionarão desde que você esteja usando o Bash.

Você pode estar interessado no fato de que a capacidade de originar um script com argumentos é um basismo. Em shou dashvocê main.shnão ecoará nada porque os argumentos para o script de origem são ignorados e $1se referem ao argumento paramain.sh.

Quando você origina o script sh, é como se você apenas copiasse e colasse o texto do script de origem no arquivo do qual ele foi originado. Considere o seguinte (observe, eu fiz a correção que Michael recomendou):

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

$ sh ./test.sh "HELLO WORLD"
HELLO WORLD

"No sh ou dash, o seu main.sh não ecoará nada porque os argumentos para o script de origem são ignorados e $ 1 se refere ao argumento para main.sh" É exatamente o que está acontecendo. Obrigado por responder.
Alguém ainda usa o MS-DOS

Marquei sua resposta como aceita, porque o problema real não estava com erros no meu script, mas principalmente porque eu igualava sh com bash, e o bash faz um péssimo trabalho emulando sh nessa situação. Sua resposta me esclareceu sobre esse problema, obrigado;
Alguém ainda usa o MS-DOS

2
Tecnicamente, é mais um kshism aqui (já existe no ksh86, provavelmente antes). @ Alguém ainda usa o seu MS-DOS, a especificação "sh" não diz o que deve acontecer se você passar argumentos adicionais; portanto, o comportamento do hífen ou do bash não é mais "sh" que o outro e é igualmente válido.
Stéphane Chazelas

16

Eu vejo três erros:

  1. Sua linha de atribuição está errada:

    $NAME="a string"

    Quando você atribui a uma variável, você não inclui o $; deveria ser:

    NAME="a string"
  2. Você está perdendo then; a linha condicional deve ser:

    if [ -f $HOME/install.sh ]; then
  3. Você não está citando $NAME, mesmo que tenha espaços. A linha de origem deve ser:

    . $HOME/install.sh "$NAME"

Ele também tem alguns outros erros, mas não acho que seja necessariamente a fonte do problema que ele traz.
Steven D

@ Steven Você está certo, havia mais algumas que eu não mencionei; funciona para mim com as correções que listei agora
Michael Mrozek

@ Steven Quando eu estava jogando o script juntos, tentei abreviá-lo para [ -f $HOME/install.sh ] && . $HOME/install.sh $NAME; Provavelmente não deveria fazer coisas assim quando procuro erros
Michael Mrozek

Parece que o outro problema que pensei estar lá realmente não é um problema, pois ele menciona especificamente o BASH.
Steven D

5

basta definir seus parâmetros antes de obter o 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;

teste

u@h$ ./main.sh some args
 i am sourced by [ main.sh ]
 with [ some args ] as parametr(s) 
u@h$

Como você define sinalizadores?
Jonathan Landrum

Edit: você, aparentemente, apenas amarrá-los após os --argumentos de comando, exatamente como:set -- -v foo -l bar -j "${bin}"
Jonathan Landrum
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.