为什么我的新 cygwin .bashrc 交互式检查不起作用?

为什么我的新 cygwin .bashrc 交互式检查不起作用?

我刚刚更新了 Cygwin,新版本.bashrc在顶部包含这一行:

echo "BEFORE TEST"
# If not running interactively, don't do anything
[[ "$-" != *i* ]] && return
echo "AFTER TEST"

我知道如果不运行交互式,您不需要执行任何操作,但我的问题是,如果我ssh使用命令:

ssh localhost pwd

我看到这个:

BEFORE TEST

因此,显然,它未通过[[ "$-" != *i* ]]测试并返回。显然ssh localhost pwd这是一个简单的例子,但.bashrc如果通过 运行命令,我希望能够一直运行ssh。我的实际自动化针对此 cygwin 实例远程运行命令,但由于路径(由 my 设置.bashrc)未正确设置而失败。

此外,任何人都可以解释该测试实际上在做什么吗?什么是i$-应该代表什么?

答案1

如果您通过 运行单个命令(pwd在您的情况下)ssh,它不是交互式 shell,因此我认为行为是正确的。

您应该将您的设置PATH为 in~/.profile~/.bash_profile,而不是 in ~/.bashrc

正如发现的bash(1)手册页:

   参数
      (...)
      特殊参数
          shell 对几个参数进行了特殊处理。这些参数可能
          仅供参考;不允许向他们分配。
          (...)
          - 扩展到调用时指定的当前选项标志
                 化,通过 set 内置命令,或由 shell 设置
                 本身(例如 -i 选项)。

因此i包含在$-意味着该-i选项已被使用(或由 shell 自动设置,是交互式的)。

答案2

恩佐替布的回答是正确的(因此被投票),但我想我应该用与通过 SSH 启动 shell 时 shell 启动相关的详细信息来补充它。

Bash 文档的读者可能想知道为什么需要.bashrc检查它是否在交互式 shell 中运行,因为 a.bashrc仅源自交互的重击贝壳。尽管如此,~/.bashrc大多数(如果不是全部)类 Unix 系统默认包含某种类型的检查(测试$-$PS1)以确保当前 shell 是交互式的。

这样做的原因是Bash 有一个远程 shell 的特殊情况。虽然非交互式 Bash shell 通常不会~/.bashrc在启动时运行命令,但当 shell 启动时会出现一种特殊情况。由远程 shell 守护进程调用:

Bash 尝试确定它何时使用连接到网络连接的标准输入运行,例如何时由远程 shell 守护程序(通常为rshd)或安全 shell 守护程序执行sshd。如果 Bash 确定它正在以这种方式运行,它会从 ~/.bashrc 读取并执行命令(如果该文件存在并且可读)。如果作为 调用,它不会执行此操作sh

欲了解更多信息,请参阅我的回答为什么 bashrc 检查当前 shell 是否是交互式的?

相关内容