重定向輸出到受許可權拒絕錯誤影響的位置?


概述

我們知道,我們可以使用 Linux shell 指令碼末尾的 “>” 運算子將 Linux shell 指令碼的標準輸出 (std out) 重定向到檔案。

有時,我們需要重定向到需要 root 許可權的檔案——例如,‘sudo command > file_requires_root_。

如果我們使用 ‘su’ 命令,即使我們使用了 ‘su’,我們也可能會收到“訪問被拒絕”的訊息。

我們將探討此問題的原因,並檢視是否有任何解決方案。

問題簡介

一個很好的例子是對問題的解釋。

假設我們有一個名為“output.txt”的空純文字文件。

kent$ ls -l /opt/output.txt
-rw-r--r-- 1 root root 0 May 8 10:43 /opt/output.txt

上面的 ls 命令顯示只有使用者“root”可以訪問“/opt/output.txt”目錄。

我們現在嘗試將 echo 語句的輸出重定向到指定的文字文件,作為普通使用者 ken −

kent$ echo "Linux is awesome!" > /opt/output.txt
bash: /opt/output.txt: Permission denied

我們收到了“訪問被拒絕”錯誤。這很容易理解。因為我們執行“echotest”指令碼並將其輸出作為 kent 帳戶重定向,但 kent 帳戶對檔案 /opt/.output.txt 沒有任何許可權。

如果我們使用“su”命令執行命令,則該命令將作為超級使用者 (root) 執行。讓我們假設使用者 kent 已獲得 sudo 許可權。

現在讓我們看看是否可以使用 sudo 將 stdout(預設輸出)重定向到我們的新文字文件 −

kent$ sudo echo "Linux is awesome!" > /opt/output.txt
[sudo] password for kent:
bash: /opt/output.txt: Permission denied

輸入密碼後,我們仍然收到相同的錯誤訊息。

我們可能會問,為什麼即使我們使用了 sudo(超級使用者)命令,也不允許我們寫入檔案?

現在我們需要找到這個問題的答案。

為什麼會出現“許可權被拒絕”錯誤?

要理解 echo 命令,我們首先需要檢查其完整的語法。該命令由兩部分組成 −

  • 命令部分:sudo echo “Linux 真棒!

  • 重定向部分:> /opt/output.txt

當我們使用 sudo(超級)許可權以 root 帳戶身份執行命令時,sudo 不會更改重定向行為。

重定向仍然由普通帳戶 ken 執行。因此,我們遇到“訪問被拒絕”錯誤。

在理解問題原因(缺乏睡眠)後,現在我們需要討論解決方案。

有幾種不同的方法可以解決這個問題。讓我們逐一看看它們。

  • 啟動“root” shell 來執行命令

  • 將命令包裝在 shell 指令碼中

  • 將重定向部分更改為命令

  • 接下來,讓我們逐一看看這三種方法。

啟動“root” Shell 來執行命令

如果我們可以以 root 使用者身份啟動互動式 bash 會話並在其中執行我們的命令,則重定向也將在 root 級別進行。

執行 sudo su −c "echo 'Hello World' > /tmp/file" 時可以使用 −s 選項來建立 root shell。

kent$ sudo -s
[sudo] password for kent:
[root]# echo "Linux is awesome!" > /opt/output.txt
[root]# exit
kent$ cat /opt/output.txt
Linux is awesome!

執行 sudo −i 後,我們現在處於具有超級使用者(或“超級使用者”)許可權的互動式 bash 會話中。然後我們可以執行整個命令並以 root 身份進行重定向。

輸出已成功儲存到目標資料夾。

將命令包裝在 shell 指令碼中

我們可以使用 sudo 將這兩個命令組合成一個命令,這意味著重定向將由超級使用者(擁有管理員許可權的使用者)執行。

我們可以使用簡單的 shell 指令碼技術將“echo”命令寫入文字檔案。

kent$ cat myScript.sh
#!/bin/bash
echo "Linux is awesome! - (shell script)" > /opt/output.txt

讓我們首先清空 output.txt 檔案,然後執行我們的指令碼。

kent$ sudo ./myScript.sh
[sudo] password for kent:
kent$ cat /opt/output.txt
Linux is awesome! - (shell script)

我們期望我們的 shell 指令碼按預期工作。

如果我們總是為帶有重定向的命令列程式建立 shell 指令碼,這可能會很不方便。

要從另一個 shell 指令碼中執行單個 shell 指令碼,我們可以使用 sudo sh −c "Script > File" 來執行第一個 shell 指令碼並將它的輸出重定向到第二個 shell 指令碼。

kent$ sudo bash -c 'echo "Linux is awesome! - (sub-shell)" > /opt/output.txt'
[sudo] password for kent:
kent$ cat /opt/output.txt
Linux is awesome! - (sub-shell)

將重定向更改為命令

從上一節我們知道,“su”命令不會影響重定向。如果我們可以將重定向更改回命令,我們可以再次使用 `su` 執行它們。

波浪號 (~) 字元用於指示備用位置。我們在這裡使用它來告訴 shell 在哪裡查詢我們的輸出。然後,我們執行 sudo 以便 shell 以 root 帳戶身份執行命令。最後,我們再次使用波浪號 (~) 字元來告訴 shell 輸出應該去哪裡。

現在我們將使用一個示例來測試這種方法。

kent$ sudo echo "Linux is awesome! - (using tee)" | sudo tee /opt/output.txt >/dev/null
[sudo] password for kent:
kent$ cat /opt/output.txt
Linux is awesome! - (using tee)

如上面的示例所示,我們已經在 output.txt 文件中計算出了預期值。

我們不需要顯示 tee 的輸出,因為我們將它的輸出重定向到 /dev/null。

結論

如果我們執行類似 sudo command > file_requires_root 的命令,我們可能會遇到“許可權被拒絕”錯誤。

我們在這裡詳細介紹了這個問題,包括它的原因、解決方案和一些避免它的最佳實踐。

更新於:2022年12月26日

580 次瀏覽

啟動您的職業生涯

完成課程後獲得認證

開始
廣告