![所有子进程都是 Bash (!),](https://linux22.com/image/49565/%E6%89%80%E6%9C%89%E5%AD%90%E8%BF%9B%E7%A8%8B%E9%83%BD%E6%98%AF%20Bash%20(!)%2C.png)
我试图使用 GDB,发现每当它试图生成我正在调试的程序时,就会生成 Bash(GDB 会说starting myProg...
,然后 Bash 就会出现。当我杀死 Bash 时,我会回到 GDB,这会告诉我 Bash 的退出状态)。起初我认为这是 GDB 的一个奇怪问题,但后来我发现尝试从 Vim 生成一个进程也只是生成了 Bash。
突然灵光一闪,我将这个问题与我的默认 shell 是 Tcsh 联系起来,并且由于我不允许更改它,所以我只是将 my 设置.tcshrc
为 contains exec bash
。当我将其更改为bash
或仅使用 Tcsh 时,问题就消失了。
我完全不知道 Tcsh 的事情是如何导致我的问题的。有谁可以提供一下吗?
顺便说一句,我能够通过运行 GDBPATH="" /usr/bin/gdb
而不仅仅是gdb
.它吐出bash: command not found
,然后继续生成我想要调试的程序。
答案1
其他答案的解释都很好。
作为解决方案,我将设置export SHELL=bash
许多命令,例如 gdb 或 screen,使用此变量来确定使用哪种 shell 来生成命令。
因此,直接使用 bash 来生成命令,而不是配置为仅启动 bash 的 tcsh。
您可以通过使用 ssh 密钥登录服务器并向authorized_keys 文件中的密钥添加强制命令来改进您的设置。
这样您就可以直接在 bash 中启动,但不会破坏任何 tcsh 脚本。
答案2
在你的 .tcshrc 文件中,你可以exec bash
像这样包装你的:
if ($?prompt) then
exec /path/to/bash
endif
$?prompt
对于非交互式 shell 将为 false,因此仅当您有交互式会话时才使用 bash。
答案3
我认为原因很明显是gdb
使用 shell 来生成进程。
Vim 确实做到了 ( help !
)
:!{cmd} Execute {cmd} with the shell.
所以当我们说:!ls -l
Vim 实际上会执行
$ SHELL -c 'ls -l'
我认为(鉴于我理解你的黑客式的设置正确)您可以通过执行exec bash -l
而不是轻松修复它exec bash
。
原因是,exec bash
(不是登录 shell)不会更改SHELL
稍后由gdb
和使用vim
并指向您的登录 shell ( tcsh
) 的环境变量。他们应该直接使用您选择的 shell ( bash
)。
笔记:您可能想想一下,当您运行一些用tcsh
.它可能不会按预期运行。
答案4
我怀疑发生的情况是,当您从 GDB 内部执行一个程序时,它会启动一个子 shell 来运行该程序,从而获取该 rc 文件。
exec 手册页显示“exec() 系列函数用新的进程映像替换当前进程映像”
我认为发生的情况是,当您在 rc 文件中调用 exec 时,它会替换您要使用 bash 运行的任何内容,然后当您退出时,您会使用 bash 退出代码返回到 GDB。如果您想将 exec 与 bash 一起使用并让您的程序运行,您可能需要弄清楚 tcsh(相当于 Bash 的 argv)在哪里存储对您想要运行的任何内容的程序调用并将其传递给 bash。
您还可以喜欢该 rc 文件并检查 argv 并确定您是否正在尝试运行程序,或者只是获取登录 shell 并基于此执行不同的行为。