Как запустить команду sudo внутри скрипта?

84

Чтобы сделать патч вручную, я должен набрать эту команду

sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  

Есть место перед 09:

sudo ./playback_delete_data_patch.sh [space] 09_delete_old_data_p.sql

Как я могу запустить это внутри скрипта?

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

user251948
источник
2
Просто поместите это в сценарий, в чем проблема?
Ли Райан
6
@LieRyan - sudo пароль - скрипт не сможет работать полностью, если кто-то там не будет, чтобы ввести его.
Уилф
Моя система просто запускает их без запроса. Ubuntu 16.04 в октябре 2017 года. Вы испортили sudoersнастройки. Ничего страшного. Это просто нужно исправить.
SDsolar
1
@ SDolar Ваша система - та, которая запуталась ; это незначительная уязвимость безопасности, которая не запрашивает пароль (делает пользователей более уязвимыми для некоторых типов атак социальной инженерии).
wizzwizz4

Ответы:

107

Это редко хорошая идея иметь sudoвнутри скрипты. Вместо этого удалите sudoиз скрипта и запустите сам скрипт с помощью sudo:

sudo myscript.sh

Таким образом, все команды в скрипте будут выполняться с правами суперпользователя, и вам нужно будет указать пароль только один раз при запуске скрипта. Если вам нужна определенная команда в скрипте для запуска без sudoпривилегий, вы можете запустить ее как обычный пользователь с помощью (спасибо Lie Ryan ):

sudo -u username command 

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

Тердон
источник
30
в скрипте могут быть команды, которым не нужна привилегия root, вы можете временно удалить привилегию root для этих команд, используя sudo -u username
Lie Ryan
48
Многие сценарии, которые я пишу, выполняют целую кучу взаимодействия с пользователем и / или проверкой ошибок. Затем одна команда в конце - что-то вроде rsync - должна быть запущена от имени пользователя root. Почему я хотел бы заставить все это работать с повышенными правами и оставить себя открытым для многих строк кода, которые могут содержать серьезные ошибки или уязвимости с корневым доступом - особенно при отладке - когда только одна или несколько команд требуют такого доступа?
Джо
2
@ Джо достаточно справедливо. Изменил «никогда не хорошая идея» на «редко».
Terdon
10
У @Joe есть действительно хорошая точка зрения здесь. Кроме того, когда кто-то говорит « не делай этого» , было бы неплохо точно знать, почему, или, по крайней мере, в каком контексте я не должен этого делать и почему
arainone
10
@terdon Вы не слушаете. Я знаю, что если вы запустите скрипт от имени пользователя root, он никогда не запросит у вас sudo. Я сравниваю это с тем, что скрипт не запускается от имени пользователя root, а вместо этого вводит sudoв скрипт явные вызовы, потому что перевод всего скрипта в корень может быть ужасной идеей, если существует всего несколько узких действий, требующих root. В этом контексте я специально отвечал на ваш комментарий: «Во многом потому, что это означает, что вы не можете запустить скрипт автоматически, поскольку вам нужно будет вводить пароль каждый раз, когда вас спрашивают».
BeeOnRope
41

Вы могли бы изменить sudoersфайл.

Беги sudo visudo.

Добавьте запись для вашего имени пользователя и сценария, который вы хотели бы запустить без запроса пароля.

username ALL=(ALL) NOPASSWD: /path/to/script
Клаус-Дитер Варцеха
источник
2
У меня не сработало, но спасибо, приятно знать, что это существует. Возможно, я неправильно понял синтаксис.
Крис К,
5
Не уверен, что кто-то упомянул об этом, но вы должны прекратить все сеансы входа в систему этого пользователя после того, как вы отредактировали sudoersфайл.
побег-ООО
1
Просто чтобы уточнить здесь, это не сценарий, который содержит строку «sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql», которая должна быть указана в файле sudoers, а сценарий play_delete_data_patch.sh или любая другая команда, которую вы хотите этому пользователю и / или их Скрипты для запуска через sudo без указания пароля.
MttJocy
19

Вы можете попробовать что-то вроде:

echo "PASSWORD" | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

Это не самая безопасная вещь, так как вы пишете пароль sudoer в виде обычного текста. Чтобы сделать его немного более безопасным, вы можете создать переменную и прочитать в нее пароль sudo, а затем выполнить команду как:

echo $PASSWORD | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

Кроме того, если вы не возражаете против того, чтобы все ваши команды выполнялись от имени пользователя root, вы можете просто выполнить свой скрипт, используя sudo, как предлагалось ранее.

sudo ./myscript
Jibbers
источник
read -s PASSWORD
Безопасное
10

Этот ответ похож на ответ Тердона . Я бы также предложил запустить основной скрипт с sudoтем, чтобы он мог работать без запроса пароля пользователя во время его выполнения.

Однако в случае, если вы хотите отбросить привилегии root для некоторых команд и запустить их как фактический пользователь, который вызвал команду sudo, вы можете проверить $SUDO_USERпеременную, чтобы выяснить исходного пользователя.

Это пример сценария того, как вы могли бы достичь этого:

#!/bin/bash

# ref: https://askubuntu.com/a/30157/8698
if ! [ $(id -u) = 0 ]; then
   echo "The script need to be run as root." >&2
   exit 1
fi

if [ $SUDO_USER ]; then
    real_user=$SUDO_USER
else
    real_user=$(whoami)
fi

# Commands that you don't want running as root would be invoked
# with: sudo -u $real_user
# So they will be run as the user who invoked the sudo command
# Keep in mind if the user is using a root shell (they're logged in as root),
# then $real_user is actually root
# sudo -u $real_user non-root-command

# Commands that need to be ran with root would be invoked without sudo
# root-command
Дэн
источник
4

На самом деле существует гораздо более простой способ сделать это. Для переносимости это моя реализация, но вы можете свободно манипулировать ею в соответствии с вашими потребностями.

Введите свой пароль sudo в качестве параметра при запуске сценария, перехватите его и повторяйте его с каждой командой, которая запросит пароль sudo.

#!/bin/bash

PW=$1
echo $PW | ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  
./command_wo_sudo.sh <param>
echo $PW | ./other_command_requires_sudo.sh <param>

Вы можете добавить подсказку и захват после запуска скрипта следующим образом:

echo "enter the sudo password, please"
read PW

Но если кто-то еще отслеживает, что работает на узле; имеет доступ к созданным им журналам; или просто просматривает ваш случайный случай при запуске теста, что может поставить под угрозу безопасность.

Это также работает с запущенными командами / сценариями, для продолжения которых требуется yes:

echo $PW | yes | ./install.sh

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

csworenx
источник
Это намного элегантнее и проще, я рад, что прокрутил все вниз! РЕДАКТИРОВАТЬ: подождите, это добавит пароль к моей истории терминала
Задание
1
Как запросить имя пользователя / пароль с помощью read: ryanstutorials.net/bash-scripting-tutorial/bash-input.php Это должно избежать этой проблемы
Задание
3
#!/bin/bash
# this declares that current user is a sudoer
sudo tee /etc/sudoers.d/$USER <<END
END

# write the content of your script here
sudo npm install hexo-cli -g
mkdir Untitled
sudo apt-get install python

# then to remove the sudo access from the current user
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k
Саньям Джайн
источник
0

Вы можете попытаться добавить пользователя, который запускает скрипт, в файл sudoers:

#give permissions to the file
sudo chmod 700 /etc/sudoers.d/useradm

sudo visudo /etc/sudoers.d/useradm

#add the following text, changing "user" but your desired user
user ALL=(ALL)NOPASSWD:ALL

#return the right permissions to the file
sudo chmod 440 /etc/sudoers.d/useradm
evinhas
источник
Вообще это плохой метод. Если вы собираетесь добавить правила sudo NOPASSWD, особенно для учетных записей, которые запускают автоматизацию, вы должны как минимум ограничить их той командой, которая выполняется (а не ВСЕ)
Кристофер Хантер,