重定向輸出到受許可權拒絕錯誤影響的位置?
概述
我們知道,我們可以使用 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 的命令,我們可能會遇到“許可權被拒絕”錯誤。
我們在這裡詳細介紹了這個問題,包括它的原因、解決方案和一些避免它的最佳實踐。