Bash

為什麼這個微不足道的 rm -rf 命令會破壞我的作業系統?

  • October 18, 2021

我使用 Bash 4.3.48(1) 並在測試 VPS 機器上執行以下命令模式:

rm -rf ${drt}/${pma}*

該命令刪除了整個作業系統(Ubuntu)。執行cd /which 只返回以下錯誤,這一點很明顯:

bash: cd /: 沒有這樣的文件或目錄

深入研究,這是因為上面原始命令中的兩個變數都沒有聲明:

  1. 我創建了一個名為的文件~/repoName/assignments_variables.sh,其中包含導出變數的列表(包括drtpma)。
  2. 而不是 running source /etc/bash.bashrc, I ran /etc/bash.bashrc,這是錯誤的,因為該文件僅與目前會話相關(儘管它可用於隨後執行文件,這些文件本身在子會話中執行數據)。

現在我很清楚錯誤的路徑是問題的一般原因,我想深入一點,問這個問題:

為什麼rm -rf忽略了錯誤的變數擴展並繼續前進/*?我知道只有在找到目錄時才rm -rf應該刪除它,因此不應該依賴不存在的目錄的部分路徑(比如導致作業系統刪除)。我如何改進命令以涵蓋將來可能出現的類似錯誤路徑(由於錯誤的變數擴展)情況?/*``rm -rf

是否有一些 Bash 指令來確保 Bash 永遠不會擴展空變數(直到我撤消該指令)?


讓我強調一下:我通常不僅使用備份,還使用雙重備份。那確實是一個在後台有 x3 備份的測試環境。

正如已經指出的那樣,這兩個變數drtpma沒有出現在您的腳本環境中,這意味著 shell 將這些變數擴展為空字元串。結果命令是rm -rf /**進一步擴展到根目錄中可用的任何內容)。

以 root 身份執行不會刪除根目錄本身rm -rf /*。另外,我(和向我指出的Jesse_b )對錯誤消息感到有些困惑

bash: cd /: No such file or directory

我自己能夠引發此錯誤消息的唯一方法是執行命令"cd /"(注意引號)。真的/被刪除了,錯誤資訊會說

bash: cd: /: No such file or directory

艾薩克已經給出了一些關於如何防止你在未來做這樣的事情的提示,但我認為我只是提出我的建議。

  • 不要在root shell 提示符下工作。

  • 如果編寫需要 root 權限sudo的腳本,請在腳本中使用實際需要這些提升權限的*特定命令。*不要以 root 身份執行整個腳本,尤其是在開發期間。

  • 您通常不需要/etc/bash.bashrc出於任何原因觸摸,並且您永遠不必明確來源它。環境變數可以在

    • 使用者自己的$HOME/.bashrc(如果腳本要從互動式會話中執行),或者
    • 在腳本本身中,或
    • 在由腳本明確提供的單獨文件(腳本編寫)中,或
    • BASH_ENV在環境變數指向的文件中。

在這種情況下可以拯救您的另一個安全措施是在 ( ) 下執行您的腳本,也可能在( )set -u下執行。shell 選項將威脅擴展未設置的變數作為錯誤,而如果命令以非零退出狀態退出,則 shell 選項將立即退出 shell 會話。nounset``set -e``errexit``nounset``errexit

劇本

#!/bin/bash -ue

echo "$hello"
echo "world"

永遠不會輸出world,而是會引發消息

script.sh: line 3: hello: unbound variable

在終止之前。(在這個簡單的例子中-u,它是終止的,-e它不做任何事情)。

如果變數不存在,擴展什麼?

讓我們試試(注意迴聲):

$ unset drt pma
$ echo rm -rf ${drt}/${pma}*
rm -rf /bin /boot /dev /etc /hello /home /initrd.img /lib /lib32 /lib64 /libx32 /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var /vmlinuz /vmlinuz.old

那是整個系統(正如您已經確認的那樣)。

問題是外殼完成的擴展。

預防

我們如何防止這種情況發生?

通過防止外殼擴展空變數。如果 var 為空或未設置,則產量

的擴展。停止執行(嚴重錯誤)。測試它:${var:?message}``message

$ echo rm -rf "${drt:?Missing variable drt}"/"${pma:?Missing variable pma}"*

該解決方案與 POSIX 兼容。

引用自:https://unix.stackexchange.com/questions/423329