5

在我阅读 bash 手册页时,.bashrc 应该只在 shell 以交互方式运行时执行。手册页将交互定义为:

交互式 shell 是在没有非选项参数且没有 -c 选项的情况下启动的,其标准输入和错误都连接到终端(由 isatty(3) 确定),或者以 -i 选项启动。PS1 已设置并且 $- 包括 i 如果 bash 是交互式的,则允许 shell 脚本或启动文件测试此状态。

然而,使用 ssh 执行命令也会导致 .bashrc 运行,这与我的预期相反,因为该命令不是以交互方式运行的。因此,这种行为似乎是一个错误,但它似乎也普遍存在于我尝试过的所有版本的 Red Hat 和 bash 中。有人可以解释为什么这种行为是正确的吗?

另外一点:即使 .bashrc 已运行,$-并且$PS设置为好像 shell 是非交互式的(如我所料)。

$ grep USER /etc/passwd
USER:x:UID:GID:UNAME:/home/USER:/bin/bash

$ cat ~/.bashrc
echo bashrc:$-,$PS1

$ bash -c 'echo $-'
hBc

$ ssh localhost 'echo $-' </dev/null 2>/dev/null
USER@localhost's password:
bashrc:hBc,
hBc

$ ssh localhost 'ps -ef | grep $$' </dev/null 2>/dev/null
USER@localhost's password:
bashrc:hBc,
USER 28296 28295 0 10:04 ? 00:00:00 bash -c ps -ef | grep $$
USER 28297 28296 0 10:04 ? 00:00:00 ps -ef
USER 28298 28296 0 10:04 ? 00:00:00 grep 28296

我目前正在通过[[ $- = *i* ]]在 .bashrc 中进行测试来解决这个问题,但似乎我不应该这样做。

一个示例服务器,在我的主目录中不包含 .bashrc(和 .ssh)以外的其他文件,具有以下配置:

$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.7 (Tikanga)

$ bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

我尝试过的 bash 版本:3.00.15、3.1.17、3.2.25、4.1.2(后者在 Red Hat 6.3 上)。

4

1 回答 1

3

来自Bash 手册

Bash 尝试确定它何时在其标准输入连接到网络连接的情况下运行,例如由远程 shell 守护程序(通常rshd)或安全 shell 守护程序执行时sshd。如果 Bash 确定它正在以这种方式运行,它会读取并执行来自 的命令~/.bashrc,如果该文件存在并且是可读的。如果作为 sh 调用,它将不会执行此操作。该--norc选项可用于禁止此行为,该--rcfile选项可用于强制读取另一个文件,但rshd通常不会使用这些选项调用 shell 或允许指定它们。

默认 Debianbashrc框架中的解决方法是将以下内容放在顶部.bashrc

# If not running interactively, don't do anything
[ -z "$PS1" ] && return
于 2013-05-14T15:51:55.273 回答