Bash, uruchom polecenie po wywołaniu nowej powłoki

12

Próbuję utworzyć taki skrypt:

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

Kiedy go wykonuję, otrzymuję nową powłokę, ale somethingjest ona wykonywana tylko wtedy, gdy wychodzę z powłoki utworzonej przez sudo -s, a nie w jej wnętrzu.

Jakaś pomoc?

Matteo
źródło

Odpowiedzi:

7

Problem jest sudo -sbez żadnego argumentu otworzy interaktywną powłokę dla roota.

Jeśli chcesz uruchomić tylko jedną komendę sudo -s, możesz po prostu:

sudo -s command

Na przykład :

$ sudo -s whoami
root

Lub możesz użyć tutaj ciągów:

$ sudo -s <<<'whoami'
root

Jeśli masz wiele poleceń, możesz użyć tutaj doc:

$ sudo -s <<'EOF'
> whoami
> hostname
> EOF
root
something--
heemayl
źródło
1
Nie warto go używać sudo -sna wypadek, rootgdyby użytkownik miał (raczej kiepski) pomysł na zmianę powłoki. Tak naprawdę powinno być to, sudo shco wyraźnie określa, której powłoki należy użyć.
Michael Le Barbier Grünewald
7

Innym sposobem byłoby przekazanie komend (y) pełnej bash do sudo:

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

Lepszym sposobem byłoby jednak uruchomienie skryptu za pomocą sudo. Nie jest to zbyt dobry pomysł, aby mieć sudowewnątrz skryptu. Zdecydowanie lepiej jest uruchomić cały skrypt z uprawnieniami roota ( sudo script.sh). W razie potrzeby możesz użyć, sudoaby usunąć uprawnienia do określonych poleceń. Na przykład:

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

Uruchomienie powyższego skryptu zwraca:

$ sudo ~/scripts/a.sh
root
/root
terdon
terdon
źródło
3

Bourne shell ma -cflagę za pomocą którego można przekazać dowolny skrypt powłoki, tak że można napisać coś podobnego

sudo sh -c 'something'

Jest to jednak przydatne tylko w przypadku najprostszych poleceń, ponieważ poprawne cytowanie skryptu jest bardzo kłopotliwe, a niedogodność jest jeszcze większa, jeśli wyślesz polecenie do zdalnego serwera przez ssh, ponieważ skrypt argumentu zostanie przeanalizowany dwukrotnie, raz z boku wysyłanie skryptu i uruchamianie skryptu z boku.

Jeśli somethingjest to złożony skrypt lub musi zostać przekazany przez linię ssh , powszechną praktyką jest pisanie funkcji, prepare_something_scriptktórej zadaniem jest pisanie skryptu „coś” na standardowym wyjściu . W najprostszej formie funkcja ta może wykorzystać dokument tutaj do wygenerowania danych wyjściowych:

prepare_something_script()
{
  cat <<EOF
something
EOF
}

Skrypt utworzony przez prepare_something_scriptmoże być następnie uruchomiony lokalnie z uprawnieniami przyznanymi przez sudo w następujący sposób:

prepare_something_script | sudo sh

W scenariuszu, w którym skrypt musi być wykonywany zdalnie z uprawnieniami nadanymi przez sudo , zwykle koduje się skrypt w bazie 64, aby uniknąć przekierowania standardowego wejścia ssh , w następujący sposób:

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

Jeśli używasz tego kodu w funkcji, nie zapomnij oznaczyć zmiennej coś 64 jako lokalną . Niektóre implementacje base64 oferują -dflagę do dekodowania, która jest gorzej obsługiwana niż --decodewariant pełny . Niektóre implementacje wymagają dodania a -w 0do polecenia kodowania, aby uniknąć fałszywych podziałów linii.

Michael Le Barbier Grünewald
źródło
0

Musisz dodać polecenie przed sudo -s, zamiast w następnym wierszu.

sudo -s something...
soumen
źródło