在 .bashrc 中使用交互命令(如脚本)时防止 fork bomb

在 .bashrc 中使用交互命令(如脚本)时防止 fork bomb

我经常想记录终端的输出。所以我尝试设置script为在启动时运行;在我的 .bashrc 文件中我输入了:

script ~/Logs/$(date "+%Y-%m-%d.%H-%M-%S")

因为每当我打开交互式终端时,.bashrc 文件中的命令都会运行,所以我认为这会实现我想要的效果。

然而,由于script它本身在执行过程中会打开一个新终端,结果却得到了一个 fork 炸弹:

Last login: Sat May  9 12:02:43 on ttys001
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
[mchenja@mycomp ~]$

关于如何确保script当我打开新的交互式终端时只运行一次,有什么提示吗?

如果这很重要的话,这是在 OS X 上,尽管我相信同样的事情也会发生在 Linux 上。

答案1

我通过“保护变量”和您的情况反思了@Thomas Dickey 的回答。这里有一些棘手的事情,这取决于您的环境。

如果您登录到运行 X windows 的工作站,则当您登录时,.bash_profile会读取该文件(通常,尽管我不能肯定地说所有版本的 Linux 都是如此;这也取决于您的登录 shell)。这会启动您的script会话,所以这是一件坏事。此外,当您从 X 内部登录到终端时,它将不会阅读.bash_profile,但仅此而已.bashrc除非你告诉终端软件告诉 bash 它是一个登录 shell,在这种情况下,恰恰会发生相反的情况。

以下是一些建议:

  • 使用 $SHLVL 来确定您是否处于 bash 的“顶层”调用中,或者可能处于 X 登录会话中,或者可能处于 X 中的术语/命令提示符中(或者可能是控制台!)。您可以使用命令tty来区分控制台登录和终端登录(tty |grep -q ^/dev/tty && echo "is console"
  • .bash_profile每次只会读取一次login session...通常。您也可以通过调用 bash 来强制读取-l
  • 如果它是一个登录 shell,.bashrc 不会是自动读取。您可以通过从内部获取来运行它.bash_profile
  • 我相信您想确保script不可重入。也就是说,如果您在正在script运行的 shell 中,并且创建了子 shell,则您不想script再次运行。
  • 如果您screen在内运行会发生什么script
  • screen具有日志记录功能,可能比脚本更合适。然后您还有其他问题,例如,当您打开多个终端窗口时会发生什么?它们每个都有单独的屏幕会话吗?

答案2

您必须设置自己的特殊变量来进行测试.bash_profile,例如,

if [ -z "$IN_MY_SCRIPT" ]
then
    export IN_MY_SCRIPT=$(date)
    script ~/Logs/$(date "+%Y-%m-%d.%H-%M-%S")
fi

答案3

我正在回答标题中的“防止分叉炸弹”问题,而不是你实际问的问题。;)

按照 PAM 的要求实施硬性nproc限制。/etc/security/limits.conf

只是一个建议:

 *        soft   nproc   500
 %users   soft   nofile  256

但这可能只会对 Apache 或 MySQL 之类的东西造成影响。

相关内容