sudo at -f

sudo at -f

如果我做:

at -f <(echo "rm $file") now + 2 hours

效果很好

但是如果我這樣做:

sudo at -f <(echo "rm $file") now + 2 hours

我得到:

at: /dev/fd/63: No such file or directory

我認為這是因為命令的處理順序所致。有什麼辦法可以使用 sudo 指令來解決這個問題嗎?我能想到的唯一方法是將命令放在腳本上並 sudo 該腳本(這是一個選項),但現在我想知道為什麼會發生這種情況。

抱歉,如果這個問題已經在某個地方得到了回答,我只是找不到它,因為我不確定要尋找什麼。

答案1

因為 shell 開啟了指向 中命令的管道<(...),並將檔案句柄傳遞給它運行的子進程(sudo在本例中)。路徑/dev/fd/63是核心提供的一種方法,允許透過普通路徑名存取已經開啟的檔案句柄。

但是,sudo不會將句柄傳遞給它運行的進程(出於安全原因):預設情況下,它會關閉除 stdin、stdout 和 stderr 之外的所有文件句柄,因此最終運行的程式沒有與 和 對應的文件/dev/fd/63句柄它出錯了。

您可以透過在 sudo 內的 shell 中進行替換來解決該問題:

sudo bash -c 'cat <(echo something)' 

當然,這意味著內部替換也以提升的特權運作:

$ sudo bash -c 'cat <(id)'
uid=0(root) gid=0(root) groups=0(root)

標誌-C提供sudo了另一種方式,但可能需要允許額外的配置:

-C num, --close-from=num
在執行命令之前關閉所有大於或等於 num 的檔案描述符。不允許小於三的值。預設情況下,sudo 在執行命令時會關閉除標準輸入、標準輸出和標準錯誤之外的所有開啟的檔案描述符。安全性策略可能會限制使用者使用此選項的能力。當管理者啟用 closefrom_override 選項時,sudoers 策略僅允許使用 -C 選項。

答案2

我假設您的意圖是將cat所有文件作為 root,您當前的ls

使用xargs管道代替可能是明智的。試試用這個:

ls | xargs sudo cat

相關內容