Як запустити команду '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

Як запустити це всередині сценарію?

Також є кілька інших команд, але ця створює проблеми.


2
Просто поставте це в сценарій, в чому проблема?
Лежати Райан

6
@LieRyan - sudo пароль - скрипт не зможе запуститися повноцінно, якщо хтось там не вводить його.
Вільф

Моя система просто запускає їх нормально, не вимагаючи. Ubuntu 16.04 в жовтні 2017 року. Ви зіпсували sudoersналаштування. Немає нічого. Це просто потрібно виправити.
SDsolar

1
@SDsolar Ваша система та, яка заплутана; це незначна вразливість безпеки, щоб не вимагати введення пароля (робить користувачів більш вразливими до деяких видів атак на соціальну інженерію).
wizzwizz4

Відповіді:


107

Вкрай рідко є ідея мати sudoвсередині сценаріїв. Натомість видаліть sudoзі сценарію та запустіть сам сценарій sudo:

sudo myscript.sh

Таким чином, всі команди в сценарії будуть запускатися з правами root, і вам потрібно буде ввести пароль лише один раз при запуску сценарію. Якщо вам потрібна певна команда в сценарії, яку потрібно запускати без sudoпривілеїв, ви можете запустити її як звичайний користувач (спасибі Lie Ryan ):

sudo -u username command 

Простір не має значення, він не повинен впливати ні на що, між командою та її аргументами завжди є пробіл.


30
в скрипті можуть бути команди, яким не потрібна привілей на root, ви можете тимчасово скинути кореневу привілей для цих команд, скориставшись іменем sudo -u
Lie Ryan

48
Багато написаних сценаріїв роблять цілу купу взаємодії користувачів та / або перевірки помилок. Потім одну команду в кінці - щось на зразок rsync - потрібно запустити як root. Чому я хотів би зробити так, щоб вся справа запускалася підвищеною і залишала себе відкритою для багатьох рядків коду, які можуть містити серйозні помилки або вразливості з кореневим доступом, особливо під час налагодження - коли лише один або кілька команд вимагають цього доступу?
Джо

2
@Joe досить справедливо. Змінили "ніколи не дуже хорошу ідею" на "рідко".
terdon

10
@Joe тут справді хороший момент. Крім того, коли хтось каже, що не роби цього , було б непогано точно знати, чому це, або, принаймні, в якому контексті я не повинен цього робити, і чому
arainone

10
@terdon Ви не слухаєте Я знаю, що якщо запустити сценарій як root, він ніколи не запропонує вам отримати sudo. Я порівнюю це з тим, що не запускати скрипт як root, а замість цього ставити явні sudoвиклики в скрипт, тому що піднесення всього сценарію до root може бути жахливою ідеєю, якщо є лише кілька вузьких дій, які потребують root. У цьому контексті я спеціально відповідав на ваш коментар: "Багато в чому тому, що це означає, що ви не можете запустити сценарій автоматично, оскільки вам потрібно буде вводити пароль щоразу, коли вас запитають".
BeeOnRope

41

Ви можете змінити sudoersфайл.

Біжи sudo visudo.

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

username ALL=(ALL) NOPASSWD: /path/to/script

2
Мені не вийшло, але дякую, добре знати, що це існує. Можливо, я неправильно зрозумів синтаксис.
Кріс К

5
Не впевнений, що хтось це згадав, але ви повинні припинити всі сеанси входу цього користувача після того, як ви відредагували sudoersфайл.
escape-llc

1
Просто для уточнення тут не той скрипт, який містить рядок "sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql", який слід вказати у файлі sudoers, але сценарій playback_delete_data_patch.sh або будь-яку іншу команду, яку ви бажаєте, щоб цей користувач та / або їх сценарії, щоб можна було запускати через sudo, не вказуючи пароль.
MttJocy

19

Ви можете спробувати щось на кшталт:

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

Це не найбезпечніше, що можна зробити, оскільки ви пишете пароль судора простим текстом. Щоб зробити його більш безпечним, ви можете створити змінну і прочитати пароль sudo в змінну, а потім ви можете виконати команду як:

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

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

sudo ./myscript

Безпечно читаючи пароль на змінну:read -s PASSWORD
Tobias Uhmann

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

Але якщо хтось інший стежить за тим, що працює на вузлі; має доступ до створених ним журналів; або просто переглядає свої випадкові випадки, коли ви запускаєте тест, що може загрожувати безпеці.

Це також працює з запущеними командами / сценаріями, для чого потрібно так, щоб продовжити:

echo $PW | yes | ./install.sh

Відлуння відповідає у відповідь на підказку, тож ви можете використовувати все необхідне там, якщо ви запускаєте інші сценарії, що мають підказки до прогресу, в послідовному порядку. Переконайтеся, що ви знаєте, що це замовлення, інакше можуть трапитися погані речі.


Це настільки елегантніше і простіше, я радий, що прокручувався весь шлях! EDIT: зачекайте, це додасть пароль до моєї історії терміналів
Job

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

Взагалі це поганий метод. Якщо ви збираєтеся додати правила судо NOPASSWD, особливо для облікових записів, які працюють з автоматизацією, вам слід принаймні обмежувати їх точною командою, яка виконується (а не ВСЕ)
Крістофер Хантер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.