1

У меня есть локальный скрипт, который хранится у моего локального пользователя (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" "$1"
  fi
done
EOF

Я выполняю вышеупомянутое как:

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

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

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

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

Скрипт пользователя sudo (testingADM.sh):

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

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

 #!/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 "$1"
./testingADM.sh "$1"
EOF

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

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

\EOF , "EOF" , 'EOF' , EOF

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

2 ответа2

1

редактировать
Из затылка. Ваш путь содержит пробелы?

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

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

1

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

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

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

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

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

Обратите внимание, что:

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

Вы должны также указать свои переменные, то есть:

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

В общем:

  • Всегда двойные кавычки переменных. (Не заключайте их в одинарные кавычки - они не расширятся.)
  • Не используйте переменную с именем path . (Как бы вы не использовали переменные, называемые user , home и т.д.)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .