Переменные не передаются из одного скрипта, вызывающего другой с bash heredoc

у меня есть shell-скрипт хранится в моем местном пользователя (executeAdM.sh), и когда я выполняю этот скрипт, я переключаюсь на пользователя sudo, принимая команды из файла инструкций. Но когда я выполняю этот сценарий, я также передаю параметры, которые на самом деле являются некоторым путем к каталогу пользователя sudo. Смотрите сценарий ниже.

скрипт для локального пользователя (executeADM.sh):

#!/bin/bash
echo password | sudo -S -l
sudo /usr/bin/su - user  <<EOF
#ls -lrt
pwd
for entry in $(ls -r)
  do
  if [ "$entry" = "testingADM.sh" ];then
    ./"$entry" ""
  fi
done
EOF

я казню выше как:

./executeADM.sh "/global/u70/globe/ADM"

когда выше сценария, это успешно переключается на другого пользователя, и с пользователем sudo я выполняю for цикл, который ищет другой скрипт с именем testingADM.sh.

как только скрипт найден, я запускаю этот скрипт с параметром, переданным от локального пользователя, и testingADM.sh должны установить путь для меня.

это не работает-он не читает параметр, переданный от локального пользователя.

сценарий пользователя sudo (testingADM.sh):

#!/bin/bash
changepath=
cd "$changepath"
pwd

когда я жестко переменная path в скрипте, все работает нормально. Но я этого не хочу:

 #!/bin/bash
 changepath=somepath
 cd "$changepath"
 pwd

вопрос вместо того, чтобы "/global/u70/globe/ADM" он принимает путь как "/global/u70/globe/", что путь после того, как я делаю sudo. Он просто не передает переменную.


С ниже предложения, это то, что я в конечном итоге с:

#!/bin/bash
echo password | sudo -S -l
sudo /usr/bin/su - user  <<EOF
#ls -lrt
#pwd
echo ""
./testingADM.sh ""
EOF

echo команда ничего не печатает; пробел отображается. Это сработало, когда я изменил EOF для EOF.

может ли кто-нибудь объяснить разницу между:

EOF , "EOF" , 'EOF' , EOF

или первые три имеют одинаковое значение? Тогда в чем разница между ними?

5
задан slhck
источник

2 ответов

не цитировать или избежать heredoc предел строки (т. е. использовать EOF вместо \EOF или "EOF"), поскольку в противном случае, специальные переменные, такие как $ не будет интерпретироваться. См.здесь для получения дополнительной информации и примеров (например, 19-7).

вот минимальный скрипт, который работает:

$ cat test.sh
#!/bin/bash
sudo su - $(whoami) <<EOF
./test2.sh ""
EOF

$ cat test2.sh
#!/bin/bash
foo=
echo "$foo"

$ ./test1.sh "/path/to/file"
"/path/to/file"

внимание:

  • нет необходимости в наследственности вообще. Просто позвони ./test2.sh сразу после sudo: sudo -u $(whoami) test2.sh ""
  • вы не должны перебирать вывод ls.
  • нет необходимости делать for цикл для поиска одного файла. Просто назовите скрипт непосредственно его именем.

вы также должны процитировать ваши переменные, то есть:

  • выполнить скрипт с ./executeADM.sh "/path/with white/space"
  • вызов ./"$entry" "" в свой скрипт
  • в другом скрипте используйте cd "$path"

In генерал:

  • всегда переменные с двойными кавычками. (Не цитируйте их по одному - они не будут расширяться.)
  • не используйте переменную path. (Как бы вы не использовали переменные с именем user,home, etc.)
1
отвечен slhck 2017-08-04 12:33:07
источник

Edit

Из задней части моей головы. Содержит ли путь пробелы?

если да, то вам нужно выполнить его как ./executeADM.sh 'somePath'.

всегда лучше сохранить в переменную, когда вы передаете ее дальше, это облегчает чтение. Я бы добавил path= тогда в пакетном файле у вас будет ./$entry "$path"

1
отвечен tukan 2017-08-04 10:45:24
источник

Другие вопросы bash linux shell-script unix