Передача змінних до сценарію bash при його пошуку


18

Припустимо, у мене є main.sh:

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

та в install.sh:

echo $1

Це, мабуть, перегукується "a string", але нічого не перегукується. Чому?


2
Не оновлюйте питання, будь ласка. Таким чином, ми не можемо побачити, що сталося з вашим початковим запитанням. Я просто повернув її назад.
Валентин Байрамі

Відповіді:


20

Майкл Мрозек висвітлює більшість питань, і його виправлення працюватимуть, оскільки ви використовуєте Bash.

Можливо, вас зацікавить той факт, що можливість джерела сценарію з аргументами - це башізм. В shабо dashвашої main.shволі не відлуння нічого , тому що аргументи в лічений сценарій ігноруються і $1буде посилатися на аргументmain.sh.

Коли ви джерело скрипту в sh, це як би ви просто копіюєте і вставляєте текст вивіреного сценарію у файл, з якого він отриманий. Розглянемо наступне (зверніть увагу, я вніс виправлення, рекомендовані Майклом):

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

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

"У sh або dash ваш main.sh нічого не буде повторюватись, оскільки аргументи до скрипту джерела ігноруються, а $ 1 буде посилатися на аргумент до main.sh" Саме так і відбувається. Дякую за відповідь.
Хтось досі використовує вас MS-DOS

Я відзначив вам відповідь прийнятою, оскільки справжня проблема полягала не в помилках у моєму сценарії, а в основному тому, що я прирівнював sh до bash, і bash виконує погану роботу з імітації sh у цій ситуації. Ваша відповідь просвітила мене щодо цього питання, дякую;
Хтось досі використовує вас MS-DOS

2
Технічно це більше кшизм (вже там, в ksh86, певно, раніше). @ SomebodystillusesyouMS-DOS, специфікація "sh" не говорить про те, що повинно відбутися, якщо ви передасте зайві аргументи, тому поведінка тире чи баш не є більш "sh", ніж інші, і однаково справедливі.
Стефан Шазелас

16

Я бачу три помилки:

  1. Рядок призначення невірний:

    $NAME="a string"

    При призначенні змінної ви не включаєте $; вона повинна бути:

    NAME="a string"
  2. Ви пропали then; умовна лінія повинна бути:

    if [ -f $HOME/install.sh ]; then
  3. Ви не цитуєте $NAME, хоча в ньому є пробіли. Рядок джерела повинен бути:

    . $HOME/install.sh "$NAME"

У нього також є кілька інших помилок, але я не думаю, що це неодмінно джерело проблеми, яку він виникає.
Стівен Д

@Steven Ти маєш рацію, було ще пару, про які я не згадував; це працює для мене з виправленими нами виправленнями
Michael Mrozek

@Steven Коли я збирав сценарій, щоб спробувати його, я скоротив його до [ -f $HOME/install.sh ] && . $HOME/install.sh $NAME; Я, мабуть, не повинен робити подібних дій, коли шукаю помилки
Майкл Мрозек

Це схоже на іншу проблему, яку я думав, що насправді це не проблема, оскільки він конкретно згадує BASH.
Стівен Д

5

просто встановіть свої параметри перед тим, як отримати скрипт!

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;

тест

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

Як ви встановлюєте прапори?
Джонатан Ландрум

Редагувати: ви, мабуть, просто нанизуєте їх після того, --як вони були аргументами команд:set -- -v foo -l bar -j "${bin}"
Джонатан Ландрум,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.