Передача переменных в скрипт 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
Технически, это больше kshism здесь (уже там в ksh86, возможно ранее). @ SomebodystillusesyouMS-DOS, спецификация "sh" не говорит, что должно произойти, если вы передадите дополнительные аргументы, поэтому поведение dash или bash не более "sh", чем другие, и одинаково допустимо.
Стефан Шазелас

16

Я вижу три ошибки:

  1. Ваша строка назначения неверна:

    $NAME="a string"

    Когда вы присваиваете переменную, вы не включаете $; так должно быть:

    NAME="a string"
  2. Ты скучаешь then; условная строка должна быть:

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

    . $HOME/install.sh "$NAME"

У него также есть несколько других ошибок, но я не думаю, что это обязательно источник проблемы, которую он поднимает.
Стивен D

@ Steven Вы правы, была еще пара, которую я не упомянул; это работает для меня с исправлениями, которые я перечислил сейчас
Майкл Мрозек

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

Похоже, что другая проблема, о которой я думал, на самом деле не проблема, поскольку он специально упоминает BASH.
Стивен D

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.