Przekazywanie zmiennych do skryptu bash podczas jego pozyskiwania

18

Załóżmy, że mam w main.sh:

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

i w install.sh:

echo $1

Ma to odbijać się echem "a string", ale nic nie odbija. Dlaczego?

Ktoś nadal używa ciebie MS-DOS
źródło
2
Proszę nie aktualizować pytania. W ten sposób nie możemy zobaczyć, co było nie tak z twoim początkowym pytaniem. Właśnie go wycofałem.
Valentin Bajrami

Odpowiedzi:

20

Michał Mrożek obejmuje większość problemów, a jego poprawki będą działać, ponieważ używasz Bash.

Być może interesuje Cię fakt, że możliwość źródłowego skryptu z argumentami to bzdura. W shlub dashtwoje main.shnic nie powtórzy, ponieważ argumenty skryptu źródłowego są ignorowane i $1będą odnosić się do argumentumain.sh.

Kiedy dodajesz skrypt do źródła sh, wygląda to tak, jakbyś po prostu skopiował i wkleił tekst źródłowego skryptu do pliku, z którego został pobrany. Rozważ następujące kwestie (uwaga, wprowadziłem poprawkę zalecaną przez Michaela):

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

$ sh ./test.sh "HELLO WORLD"
HELLO WORLD
Steven D.
źródło
„W sh lub dash twoja strona main.sh nie będzie nic powtarzać, ponieważ argumenty skryptu źródłowego są ignorowane, a $ 1 będzie odnosić się do argumentu main.sh” Tak właśnie się dzieje. Dzięki za odpowiedź.
Ktoś nadal cię używa MS-DOS
Oznacziłem twoją odpowiedź jako zaakceptowaną, ponieważ prawdziwym problemem nie były błędy w moim skrypcie, ale głównie dlatego, że utożsamiłem sh z bash, a bash źle radzi sobie z emulowaniem sh w tej sytuacji. Twoja odpowiedź powiększyła mnie o tę kwestię, dzięki;
Ktoś nadal cię używa MS-DOS
2
Technicznie jest to raczej kshizm (już w ksh86, prawdopodobnie wcześniej). @ SomebodystillusesyouMS-DOS, specyfikacja „sh” nie mówi, co powinno się stać, jeśli przekażesz dodatkowe argumenty, więc zachowanie myślnika lub bash nie jest już bardziej „sh” niż inne i są jednakowo prawidłowe.
Stéphane Chazelas
16

Widzę trzy błędy:

  1. Twoja linia przydziału jest nieprawidłowa:

    $NAME="a string"

    Kiedy przypisujesz do zmiennej, nie dołączasz $; powinno być:

    NAME="a string"
  2. Brakuje ci then; linia warunkowa powinna być:

    if [ -f $HOME/install.sh ]; then
  3. Nie cytujesz $NAME, chociaż ma spacje. Linia źródłowa powinna być:

    . $HOME/install.sh "$NAME"
Michał Mrożek
źródło
Ma też kilka innych błędów, ale nie sądzę, że jest to źródło problemu, który porusza.
Steven D,
@Steven Masz rację, było jeszcze kilka, o których nie wspomniałem; działa na mnie z poprawkami, które teraz wymieniłem
Michael Mrozek
@Steven Kiedy składałem skrypt, aby go wypróbować, skróciłem go [ -f $HOME/install.sh ] && . $HOME/install.sh $NAME; Prawdopodobnie nie powinienem robić takich rzeczy, kiedy szukam błędów
Michał Mrożek
Wygląda to na inny problem, o którym myślałem, że tak naprawdę nie ma problemu, ponieważ konkretnie wspomina BASH.
Steven D
5

po prostu ustaw parametry przed pozyskaniem skryptu!

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$
Jonasz
źródło
Jak ustawić flagi?
Jonathan Landrum
Edycja: najwyraźniej po prostu napisałeś je po tym, --jak argumenty dowodzenia:set -- -v foo -l bar -j "${bin}"
Jonathan Landrum