Bash, выполни команду после вызова новой оболочки

12

Я пытаюсь сделать такой скрипт:

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

Когда я ее выполняю, я получаю новую оболочку, но somethingона запускается только при выходе из созданной оболочки sudo -s, а не внутри нее.

Любая помощь?

Matteo
источник

Ответы:

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--
heemayl
источник
1
Это не очень хорошо, sudo -sесли у rootпользователя есть (довольно плохая) идея сменить оболочку. Это должно быть то, sudo shчто явно указывает, какая оболочка будет использоваться.
Майкл Ле Барбье Грюневальд,
7

Другим способом было бы передать полную команду (и) bash sudo:

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

Тем не менее, лучше всего было бы запустить скрипт с sudoвместо этого. Это не очень хорошая идея, чтобы иметь sudoвнутри сценария. Гораздо лучше запустить весь скрипт с правами суперпользователя ( 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, обычно кодируют скрипт в base 64, чтобы избежать перенаправления стандартного ввода ssh , например так:

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

Если вы используете этот код в функции, не забудьте пометить переменную something64 как локальную . Некоторые реализации base64 предлагают -dфлаг для декодирования, который менее хорошо поддерживается, чем подробный --decodeвариант. В некоторых реализациях требуется добавить a -w 0в команду кодирования, чтобы избежать ложных разрывов строк.

Михаэль Ле Барбье Грюневальд
источник
0

Вам нужно добавить команду перед sudo -s, а не в следующей строке.

sudo -s something...
soumen
источник