例如,如果我想創建一個文件並在一行中輸入文本,我可以使用運算符將輸出重定向到文件中>
:
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 要求將first
和last
數字傳遞給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 中的別名,但那也一樣好。 fc
hist
答案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