如何停止 bash shell 扩展?

如何停止 bash shell 扩展?

我知道一些停止进程的方法。当我输入:

echo {1..999999} > filename.txt 

我无法阻止它运行。我可以使用Ctrl+ C|停止其他进程 Ctrl+ D| Ctrl+\等等。但他们似乎都没有使用这个命令。

有些人告诉我只需关闭这个终端即可。除此之外,打开新终端杀死所有终端进程,但我不想这样做。我想在服务器中我不会有这样的机会打开新终端。

我可以在文本模式下打开一个新的终端会话吗?

答案1

Ctrl无法使用- etc...中断该操作的原因c是 shell 此时没有运行任何命令。{1..999999}一旦到达运行命令的点,它就会忙于扩展以计算命令行参数最终会是什么。

虽然外部命令响应终止信号(当您按-SIGINT时默认发出),但 shell 本身会忽略它们。如果他们没有,那么,当您按下-时,除了杀死正在运行的任何命令之外,您还会杀死 shell 本身! (由于 tty 作业控制以及前台和后台进程组的原因,这并不完全正确,但对于解释的目的来说已经足够接近了。)CtrlcCtrlc

如果您需要中断它,不幸的是您只能杀死 shell 本身。终止 shell 本身将导致您的会话终止。从这个意义上说,它很大程度上相当于关闭终端窗口或终止 SSH 连接。

答案2

ctrl如果您想要一个可以用+停止的替代方案c,则可以在 bash 中执行以下操作:

i=1; while [ $i -le 999999 ]; do echo $((i++)) >> filename.txt; done

请务必使用重定向符号1 >>追加到文件而不是覆盖它。


另外,当使用括号在子 shell 中运行命令时,我似乎可以用ctrl+来停止它。请注意,由于 Celada 解释的原因,永远不会创建输出文件。c( echo {1..999999} > numero.txt )

子 shell - 高级 Bash 脚本指南


为了进一步支持 Celada 的答案,下面是 bash shell 的 fork-and-exec 方案的运行顺序。您可以看到,直到执行 shell 扩展之后才会执行该命令;尚未创建分叉。在命令中echo {1..999999} > filename.txt,父 shell正在执行外壳扩展的过程。ctrl+c当然,不会杀死父 shell。

Bash 初学者指南 1.4.1.1。外壳语法

如果输入没有注释,shell 会读取它并将其分为单词和运算符,使用引用规则来定义输入的每个字符的含义。然后,这些单词和运算符被翻译成命令和其他结构,返回可用于检查或处理的退出状态。上述 fork-and-exec 方案仅在 shell 按以下方式分析输入后应用:

  • shell 从文件、字符串或用户终端读取输入。

  • 输入被分解为单词和运算符,遵循引用规则,请参阅第 3 章。这些标记由元字符分隔。执行别名扩展。

  • shell 将标记解析(分析和替换)为简单命令和复合命令。

  • Bash 执行各种 shell 扩展,将扩展的标记分解为文件名、命令和参数列表。

  • 如有必要,将执行重定向,重定向运算符及其操作数将从参数列表中删除。

  • 命令被执行。

  • (可选)外壳程序等待命令完成并收集其退出状态。

Bash 初学者指南 3.4.1。一般的

命令被分割成标记(参见第 1.4.1.1 节)后,这些标记或单词将被扩展或解析。执行了八种扩展,我们将在下一节中按扩展顺序讨论它们。

大括号扩展是执行扩展顺序中的第一个。


停止 Shell 扩展

kill -SIGSTOP <pid>实际上,您可以通过发送到 shell 的 pid 来停止 shell 扩展。echo $$将给出当前 shell 的 pid,或者您可以尝试pgrep -l bash确定哪个 shell 正在运行扩展。

可以使用 来从中断处恢复扩展kill -SIGCONT <pid>

除了杀死父外壳或让它完成之外,我不知道有什么方法可以杀死扩展。对我来说,这是在子 shell 中运行扩展的一个很好的例子。

相关内容