Bash

中斷 shell 命令行擴展

  • August 6, 2018

警告:請勿在不了解其含義的情況下嘗試此問題中列出的命令。

抱歉,如果這是重複的。我很驚訝地發現一個簡單的命令

echo $(yes)

凍結了我的電腦(實際上它嚴重滯後於電腦而不是凍結,但滯後嚴重到讓人認為它已凍結)。鍵入Ctrl``CCtrl``Z在鍵入此命令後立即鍵入似乎並不能幫助我從這個輸入錯誤的命令中恢復。

另一方面

ls /*/../*/../*/../*/../*/

是一個眾所周知的漏洞,它也會嚴重滯後於電腦的最佳狀態,並使電腦崩潰到最壞的狀態。

請注意,這些命令與眾所周知的 fork 炸彈完全不同。

**我的問題是:**有沒有辦法在我開始在 shell 中執行這些命令後立即中斷這些命令,這些命令會建立大量的 shell 命令行選項?

我的理解是,由於shell擴展是在命令執行之前完成的,因此中斷命令的通常方法不起作用,因為發生滯後時命令甚至沒有執行,但我也想確認我的理解是正確的,並且我非常有興趣了解在它使用太多記憶體之前取消 shell 擴展的任何方法。

我不是在尋找核心如何在低記憶體下工作。當系統已經嚴重滯後時,我也不會尋找SysRq可能有用的過度殺傷力。我也不是在尋找諸如強加ulimit記憶之類的預防性方法。我正在尋找一種方法,可以在它滯後於系統之前從 shell 本身中有效地取消一個巨大的 shell 擴展過程。我不知道這是否可能。如果按照評論不可能,也請留下一個答案,最好附上解釋。

我選擇不在原始問題中包含任何特定於系統的資訊,因為我想要一個一般性的答案,但如果這很重要,這裡是關於我的系統的資訊:Ubuntu 16.04.4 LTS使用gnome-terminaland bash 4.3.48(1),執行x86_64系統。不涉及虛擬機。

截至目前,GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)我沒有使用虛擬機:

echo $(yes) 

存在外殼並且不會凍結系統,並且:

ls /*/../*/../*/../*/../*/

返回

bash: /bin/ls: Argument list too long

但作為一項規則,當您處理可以獲取系統所有資源的事情時,最好在執行之前設置限制,如果您知道一個程序可能是一個 CPU 豬,您可以啟動它cpulimit或執行renice.

如果你想限制已經啟動的程序,你必須通過 PID 一個一個地做,但你可以有一個批處理腳本來做,如下所示:

#!/bin/bash
LIMIT_PIDS=$(pgrep tesseract)   # PIDs in queue replace tesseract with your name
echo $LIMIT_PIDS
for i in $LIMIT_PIDS
do
   cpulimit -p $i -l 10 -z &   # to 10 percent processes
done

就我而言pypdfocr,啟動貪婪tesseract

在某些情況下,如果您的 CPU 非常好,您可以使用renice這樣的:

watch -n5 'pidof tesseract | xargs -L1 sudo renice +19'

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