Bash, виконайте команду після виклику нової оболонки


12

Я намагаюся зробити такий сценарій:

#!/bin/bash
sudo -s
something...

Коли я його виконую, я отримую нову оболонку, але somethingвиконується лише тоді, коли я виходжу із створеної оболонки sudo -s, а не всередині неї.

Будь-яка допомога?

Відповіді:


7

Проблема sudo -sбез жодних аргументів відкриє інтерактивну оболонку для root.

Якщо ви просто хочете запустити одну команду за допомогою sudo -s, ви можете просто зробити:

sudo -s command

Наприклад :

$ sudo -s whoami
root

Або ви можете використовувати тут рядки:

$ sudo -s <<<'whoami'
root

Якщо у вас є кілька команд, ви можете використовувати тут doc:

$ sudo -s <<'EOF'
> whoami
> hostname
> EOF
root
something--

1
Недобре використовувати sudo -sлише на випадок, якщо у rootкористувача була (досить погана) ідея змінити свою оболонку. Це дійсно повинно бути sudo shчітко зазначено, яку оболонку потрібно використовувати.
Майкл Ле Барб'є Грюневальд

7

Іншим способом буде передача повних команд bash sudo:

#!/bin/bash
sudo bash -c 'command1; command2; command3;'

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

#!/usr/bin/env bash
whoami
echo $HOME
sudo -u terdon whoami  ## drop privileges for specific command.

Запуск сценарію вище повертається:

$ sudo ~/scripts/a.sh
root
/root
terdon

3

Bourne оболонка має -cпрапор , який ви можете використовувати , щоб передати довільний сценарій в оболонку, так що ви можете написати що - щось на зразок

sudo sh -c 'something'

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

Якщо somethingскладний скрипт або його потрібно передати через ssh- рядок, звичайною практикою є написання функції prepare_something_script, завданням якої є написання сценарію «щось» у stdout . У своїй найпростішій формі ця функція може використовувати тут документ для отримання результатів:

prepare_something_script()
{
  cat <<EOF
something
EOF
}

Сценарій, створений програмою, prepare_something_scriptможе бути виконаний локально за допомогою привілеїв, наданих sudo таким чином:

prepare_something_script | sudo sh

У сценарії, коли сценарій повинен виконуватися віддалено з привілеями, наданими sudo , прийнято кодувати скрипт у базі 64, щоб уникнути перенаправлення стандартного вводу ssh , як це:

something64=$(prepare_something_script | base64)
ssh usesr@remote-host "echo ${something64} | base64 --decode | sudo sh"

Якщо ви використовуєте цей код у функції, не забудьте позначити змінну something64 як локальну . Деякі реалізації base64 пропонують -dпрапор для розшифровки, який менш добре підтримується, ніж вербологічний --decodeваріант. Деякі реалізації вимагають додати -w 0до команди кодування, щоб уникнути помилкових розривів рядків.


0

Потрібно додати команду перед sudo -s, а не в наступному рядку.

sudo -s something...
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.