用一個 sudo 執行一行指令

用一個 sudo 執行一行指令

例如,如果我想創建一個文件並在一行中輸入文本,我可以使用運算符將輸出重定向到文件中>

echo "something" > /path/foobar

但如果我沒有權限存取該資料夾/path/並且需要 sudo 權限,我如何才能像具有 sudo 權限的普通使用者一樣實現相同的命令?

我試過

sudo echo "something" > /path/foobar

但這是行不通的,因為 sudo 只edit計算
>

sudo su當然,我可以在使用或使用之前成為root tee

echo "something" | sudo tee /path/foobar

但我想找到一個解決方案,我可以透過以下方式使用最後一行作為替換

sudo !!

有沒有辦法“回收”最後一行並添加sudo到前面?

答案1

您不能只停留sudo在 shell 命令前面,您必須呼叫 shell 來再次評估該命令(執行諸如擴展變數、為重定向運算子開啟檔案等操作)。所以那是

sudo bash -c !!

只是這不太有效,因為!!插入了上一個指令的文字、特殊字元等等。您需要以字串形式檢索命令文字並將其作為參數傳遞給sh.幸運的是,bashfc內建讓你做到這一點。

sudo bash -c "$(fc -ln -1)"

或者甚至,請確保調用當前正在運行的相同版本的 bash:

sudo "$BASH" -c "$(fc -ln -1)"

請注意,由於該命令是在單獨的 shell 進程中執行的,因此它繼承環境變數(僅保留那些sudo,請注意),但不繼承 shell 內部變數。 Shell 選項(例如kshglob)和其他設定也將從預設值開始。

相同的指令²適用於 zsh 和 ksh,但 ATT ksh93 要求將firstlast數字傳遞給fc³(也適用於 bash、zsh 和 pdksh/mksh):

sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"

$0只有在透過 $PATH 呼叫 shell 且 $PATH 未變更或透過絕對路徑呼叫 shell 時,用於指定正在執行的 shell 的可執行檔才有效。

這是 zsh 中的另一種方法,它稍微清晰一些,但更長:

sudo zsh -c $history[$[HISTCMD-1]]

最後的警告sudo是:針對潛在危險的命令。不要讓它太容易使用它!

¹開頭有一些額外的空格,指令替換會刪除結尾處的換行符,但 shell 的語法並不在乎這一點。
²我不認為 zsh 或 ksh 有像 bash 那樣的東西$BASH$0只有當它是絕對路徑或不包含斜線且命令搜尋路徑未更改時才有效。
³是 ATT ksh 中的別名,但那也一樣好。 fchist

答案2

如果你想重做相同的命令須藤!執行如下命令後:

echo "something">/path/file

您可以使用全域替換語法來呼叫命令:

!!:gs/>/|sudo tee -a /

在後面使用一個空格-A範圍。

這相當於須藤!但可以幫助您繞過 < 和 > 的 sudo 限制。因為 sudo 不允許使用 [<, >]。


要繞過重定向的 sudo 限制,您可以像這樣使用它:

echo "something" | sudo tee myfile

tee 命令將允許您從標準輸入讀取並寫入標準輸出和文件

如果您想要重複該命令並將文字附加到檔案中,則 tee 命令具有-A附加選項。所以你可以用以下命令回憶命令

sudo !!

並且文字將被附加到文件中

例子:

echo "something" | sudo tee -a /path/file
sudo !!

答案3

這似乎很簡單sudo sh -c "!!"

$ cd /
$ echo hello > foo
bash: foo: Permission denied
$ sudo sh -c "!!"
sudo sh -c "echo hello > foo"
$ ls -l foo
-rw-r--r-- 1 root root 6 Jun 20 16:21 foo

相關內容