Nie możesz po prostu sudo
stać przed poleceniem powłoki, musisz wywołać powłokę, aby ponownie ocenić to polecenie (robiąc takie rzeczy, jak rozszerzanie zmiennych, otwieranie plików dla operatorów przekierowania itp.). Więc to jest
sudo bash -c !!
poza tym, że to nie do końca działa, ponieważ !!
interpoluje tekst poprzedniego polecenia, znaków specjalnych i wszystkich innych. Musisz pobrać tekst polecenia jako ciąg znaków i przekazać go jako argument do sh
. Na szczęście fc
wbudowane bash pozwala ci to zrobić¹.
sudo bash -c "$(fc -ln -1)"
Lub nawet, aby mieć pewność, że uruchomisz tę samą wersję bash, która jest obecnie uruchomiona:
sudo "$BASH" -c "$(fc -ln -1)"
Zauważ, że ponieważ polecenie jest wykonywane w osobnym procesie powłoki, dziedziczy zmienne środowiskowe (tylko te, które sudo
zachowują, pamiętaj), ale nie wewnętrzne zmienne powłoki. Opcje powłoki (np. kshglob
) I inne ustawienia zostaną uruchomione domyślnie.
To samo polecenie² działa w zsh i ksh, chociaż ATT ksh93 wymaga, aby zarówno first
and, jak i last
liczba zostały przekazane do fc
³ (co działa również w bash, zsh i pdksh / mksh):
sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"
Użycie $0
oznaczenia pliku wykonywalnego działającej powłoki działa tylko wtedy, gdy powłoka została wywołana przez $ PATH, a $ PATH nie uległa zmianie lub przez ścieżkę bezwzględną.
Oto kolejna metoda w Zsh, która jest nieco jaśniejsza, ale dłuższa:
sudo zsh -c $history[$[HISTCMD-1]]
Ostatnie słowo ostrzeżenia: sudo
dotyczy potencjalnie niebezpiecznych poleceń. Nie rób tego zbyt łatwo z niego korzystać!
¹ Na początku jest trochę białych spacji, a podstawianie poleceń usuwa nowe linie na końcu, ale składnia powłoki nie dba o to.
² Nie sądzę, aby Zsh lub Ksh miały coś takiego jak bash $BASH
; $0
działa tylko wtedy, gdy jest to ścieżka bezwzględna lub gdy nie zawiera ukośnika, a ścieżka wyszukiwania poleceń nie uległa zmianie.
³ jest pseudonimem dla ATT ksh, ale to jest równie dobre. fc
hist