为什么子shell不继承导出变量(PS1)?

为什么子shell不继承导出变量(PS1)?

我用它startx来启动图形环境。我有一个非常简单的.xinitrc,我将在设置环境时添加一些东西,但现在它如下:

catwm & # Just a basic window manager, for testing.

xterm

exit我之所以将 WM 和前台终端设为后台,而不是像通常那样反过来,是因为我希望在输入后能够返回到虚拟文本控制台xterm。这似乎按描述的方式工作。

问题是,PS1当前设置为我的偏好的变量/etc/profile.d/user.sh(源自/etc/profile发行版提供的)似乎没有传播到上述环境中xterm。相关进程树如下:

\_ -bash
    \_ xinit /home/user/.xinitrc -- /etc/X11/xinit/xserverrc :0 -auth /tmp/serverauth.ggJna3I0vx
        \_ /usr/bin/X -nolisten tcp :0 -auth /tmp/serverauth.ggJna3I0vx vt1
        \_ sh /home/user/.xinitrc
            \_ /home/user/catwm
            \_ xterm
                \_ bash

启动的 shellxterm似乎是交互式的,但执行的 shell.xinitrc不是。我对这两种情况都满意,关于交互性的假设似乎完全有效,但现在我有一个非交互式 shell,它会间接生成一个交互式 shell,而交互式 shell 没有机会自动继承提示符,因为提示符未设置或在进程树的更高层不可用。我该如何找回我的提示符?

答案1

命令envexport仅列出导出的变量。$PS1通常不导出。echo $PS1在 shell 中尝试查看 的实际值$PS1

非交互式 shell通常没有$PS1。非交互式bash明确取消设置$PS11您可以使用bash来检查是否是交互式的echo $-。如果输出包含i则它是交互式的。您可以使用命令行上的选项明确启动交互式 shell:bash -i。以 启动的 shell-c不是交互式的。

/etc/profile脚本已为登录 shell 读取。您可以通过以下方式将 shell 作为登录 shell 启动:bash -l

使用bashshell脚本/etc/bash.bashrc~/.bashrc通常用于设置$PS1。这些脚本是在启动交互式非登录 shell 时调用的。这是您在 中的情况xterm请参阅永久设置 PS? 字符串

可能的解决方案

  • xterm以登录 shell 形式启动内部 shell: bash -l。检查是否/etc/profile~/.profile包含仅在登录后执行的代码。可能需要对脚本进行轻微修改。
  • 使用不同的 shell。例如,dash不会取消设置$PS1。您可以将此类 shell 用作非交互式 shell,它将运行脚本直至xterm
  • 放弃严格的 POSIX 合规性并使用 bash 标准位置来设置$PS1:/etc/bash.bashrc~/.bashrc
  • 放弃严格的 POSIX 合规性并提供您自己的启动脚本,例如:bash --rcfile <(echo "PS1=$PS1save") -i
  • 启动中间 shellstartxxterm 作为交互式外壳bash -i)。不幸的是,这可能会产生一些副作用,因此我不会这么做。

相关内容