Mam system, do którego mogę się logować tylko pod moją nazwą użytkownika (myuser), ale muszę uruchamiać polecenia jako inny użytkownik (scriptuser). Do tej pory wymyśliłem następujące polecenia, aby uruchomić potrzebne mi polecenia:
ssh -tq myuser@hostname "sudo -u scriptuser bash -c \"ls -al\""
Jeśli jednak, gdy spróbuję uruchomić bardziej złożone polecenie, takie jak [[ -d "/tmp/Some directory" ]] && rm -rf "/tmp/Some directory"
szybko, mam problem z cytowaniem. Nie jestem pewien, w jaki sposób mógłbym przekazać to przykładowe złożone polecenie bash -c
, gdy \"
już wyznaczam granice przekazywanego polecenia (a więc nie wiem, jak cytować katalog / tmp / Some, który zawiera spacje.
Czy istnieje ogólne rozwiązanie pozwalające mi przekazać dowolne polecenie bez względu na to, jak skomplikowane / szalone jest cytowanie, czy też jest to jakieś ograniczenie, które osiągnąłem? Czy istnieją inne możliwe i być może bardziej czytelne rozwiązania?
Odpowiedzi:
Trik, którego czasami używam, to użycie base64 do kodowania poleceń i potokowanie go w celu uderzenia w drugą stronę:
Spowoduje to zakodowanie skryptu ze wszystkimi przecinkami, ukośnikami odwrotnymi, cudzysłowami i zmiennymi wewnątrz bezpiecznego ciągu i wysłanie go na inny serwer. (
-w0
jest wymagany do wyłączenia zawijania linii, co domyślnie ma miejsce w kolumnie 76). Z drugiej strony,$(base64 -d)
dekoduje skrypt i podaje go do bash, aby został wykonany.Nigdy nie miałem z tym żadnego problemu, bez względu na to, jak skomplikowany był skrypt. Rozwiązuje problem ucieczki, ponieważ nie musisz niczego uciekać. Nie tworzy pliku na zdalnym hoście i możesz z łatwością uruchamiać bardzo skomplikowane skrypty.
źródło
ssh user@remotehost "echo `base64 -w0 script.sh` | base64 -d | sudo bash"
base64 script | ssh remotehost 'base64 -d | sudo bash'
wystarczyłoby :)Widzisz
-tt
opcję? Przeczytajssh(1)
instrukcję.Często używam vima i
:!cat % | ssh -tt somemachine
trików.źródło
:!cat % | (command)
można to zrobić jako:w !(command)
lub:!(command) < %
.ssh -tt
powoduje, że mój ssh nie kończy się po uruchomieniu niektórych poleceń (dodawanieexit
na końcu nie pomaga)Myślę, że najłatwiejszym rozwiązaniem jest modyfikacja komentarza @ thanasisk.
Utwórz skrypt
scp
na maszynie, a następnie uruchom go.Miej
rm
sam skrypt na początku. Powłoka otworzyła plik, więc został załadowany i można go bez problemu usunąć.Wykonując czynności w tej kolejności (
rm
po pierwsze, inne po drugie), zostanie nawet usunięty, gdy w pewnym momencie zawiedzie.źródło
Możesz użyć specyfikatora
%q
formatu,printf
aby zająć się zmienną dla Ciebie:printf -v
zapisuje dane wyjściowe do zmiennej (w tym przypadku$cmd_str
). Myślę, że to najprostszy sposób na zrobienie tego. Nie ma potrzeby przesyłania żadnych plików ani kodowania ciągu poleceń (tak jak lubię lewę).Oto bardziej złożony przykład pokazujący, że działa również w przypadku nawiasów kwadratowych i ampersandów:
Nie testowałem tego,
sudo
ale powinno to być tak proste, jak:Jeśli chcesz, możesz pominąć krok i uniknąć tworzenia zmiennej pośredniej:
Lub nawet po prostu unikaj tworzenia zmiennej całkowicie:
źródło
Oto „poprawny” (syntaktyczny) sposób wykonania czegoś takiego w bash:
Aby uzyskać dokładne wyjaśnienie, jak to działa, zobacz https://stackoverflow.com/a/21761956/111948
źródło
Czy wiesz, że możesz użyć,
sudo
aby dać ci powłokę, w której możesz uruchamiać polecenia jako wybrany użytkownik?źródło
Możesz zdefiniować skrypt na komputerze lokalnym, a następnie
cat
przesłać go do zdalnego komputera:źródło
sudo -u scriptuser
? Czy heredoc byłby użyteczny, biorąc pod uwagę, że muszę mieć zmienne w skrypcie, który przesyłam do komputera?echo "sudo `cat fileForSsh.txt`" | ssh ...
ale ciągle dostajęsudo: sorry, you must have a tty to run sudo
./etc/sudoers
zmienić plikssh -tq user@host "sudo bash -s" < test.sh
Proste i łatwe.
źródło
Jeśli używasz wystarczająco nowoczesnej powłoki Bash, możesz umieścić swoje polecenia w funkcji i wydrukować tę funkcję jako ciąg znaków
export -p -f function_name
. Wynik tego ciągu może następnie zawierać dowolne polecenia, które niekoniecznie muszą być uruchamiane jako root.Przykład użycia potoków z mojej odpowiedzi na Unix.SE :
Przykład, który pobiera, zapisuje plik dla zalogowanego użytkownika i instaluje program root:
Jeśli chcesz uruchomić całą komendę
sudo
, możesz użyć tego:źródło
Oto moje (nie tak naprawdę przetestowane) gówniane rozwiązanie:
Nie możesz zrobić:
Następnym krokiem jest utworzenie
betterssh
skryptu, który już to robi:źródło
Dla tych z was, którzy muszą przekazać parametry do skryptu, powinno to wyglądać następująco:
źródło
Najpierw utwórz skrypt lokalny, a następnie uruchom go zdalnie za pomocą następującego polecenia:
źródło