Passando le variabili a uno script bash durante l'approvvigionamento


18

Supponiamo di avere in main.sh:

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

e in install.sh:

echo $1

Questo dovrebbe echeggiare "a string", ma non riecheggia nulla. Perché?


2
Non aggiornare la domanda per favore. In questo modo non possiamo vedere cosa non andava nella tua domanda iniziale. L'ho appena riavviato.
Valentin Bajrami,

Risposte:


20

Michael Mrozek copre la maggior parte dei problemi e le sue correzioni funzioneranno da quando usi Bash.

Potresti essere interessato al fatto che la capacità di procurarsi una sceneggiatura con argomenti sia un bashismo. In sho la dashtua main.shvolontà non farà eco perché gli argomenti dello script di provenienza vengono ignorati e $1faranno riferimento all'argomentomain.sh.

Quando si genera lo script sh, è come se si copiasse e incollasse il testo dello script di origine nel file da cui era stato originato. Considera quanto segue (nota, ho apportato la correzione raccomandata da Michael):

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

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

"In sh o dash il tuo main.sh non farà eco perché gli argomenti dello script di provenienza vengono ignorati e $ 1 farà riferimento all'argomento di main.sh" Questo è esattamente ciò che sta accadendo. Grazie per aver risposto.
Qualcuno usa ancora MS-DOS il

Ho contrassegnato la tua risposta come accettata, perché il vero problema non era con gli errori nella mia sceneggiatura, ma principalmente perché ho identificato sh con bash, e bash fa un pessimo lavoro di emulare sh in questa situazione. La tua risposta mi ha illuminato di questo problema, grazie;
Qualcuno usa ancora MS-DOS il

2
Tecnicamente, è più un kshism qui (già lì in ksh86, probabilmente prima). @ SomebodystillusesyouMS-DOS, la specifica "sh" non dice cosa dovrebbe accadere se passi argomenti aggiuntivi, quindi il comportamento trattino o bash non è più "sh" dell'altro e sono ugualmente validi.
Stéphane Chazelas,

16

Vedo tre errori:

  1. La tua riga di assegnazione è errata:

    $NAME="a string"

    Quando si assegna a una variabile non si include il $; dovrebbe essere:

    NAME="a string"
  2. Ti stai perdendo then; la linea condizionale dovrebbe essere:

    if [ -f $HOME/install.sh ]; then
  3. Non stai citando $NAME, anche se ha spazi. La linea di origine dovrebbe essere:

    . $HOME/install.sh "$NAME"

Ha anche alcuni altri errori, ma non penso che sia necessariamente la fonte del problema che solleva.
Steven D,

@Steven Hai ragione, ce n'erano un altro paio di cui non ho parlato; funziona per me con le correzioni che ho elencato ora
Michael Mrozek

@Steven Quando stavo mettendo insieme la sceneggiatura per provarla, l'ho abbreviata in [ -f $HOME/install.sh ] && . $HOME/install.sh $NAME; Probabilmente non dovrei fare cose del genere quando cerco errori
Michael Mrozek

Sembra che l'altro problema che pensavo fosse in realtà non è un problema poiché menziona specificamente BASH.
Steven D,

5

basta impostare i parametri prima di approvvigionare lo 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;

test

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

Come si impostano le bandiere?
Jonathan Landrum,

Modifica: apparentemente li incuriosisci subito dopo --proprio come fossero argomenti di comando:set -- -v foo -l bar -j "${bin}"
Jonathan Landrum,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.