为什么即使正确指定了 $PATH,Bash 也无法找到命令?

为什么即使正确指定了 $PATH,Bash 也无法找到命令?

我在文件中指定命令的路径/etc/配置文件:

export PATH=$PATH:/usr/app/cpn/bin

我的命令位于:

$ which ydisplay 
/usr/app/cpn/bin/ydisplay

因此,当我执行“echo $PATH”时,输出如下所示:

$ echo $PATH
...:/usr/app/cpn/bin

一切正常,但是当我尝试通过 SSH 启动命令时,出现错误:

$ ssh 127.0.0.1 ydisplay
$ bash: ydisplay: command not found

但我的路径仍然存在:

$ ssh 127.0.0.1 echo $PATH
...:/usr/app/cpn/bin

请解释为什么 Bash 在 SSH 会话期间无法找到 ydisplay 以及如何正确配置 SSH 以避免此问题。

更重要的是,如果我在当前用户的本地文件 .bashrc 中指定 $PATH ,则一切正常。但我只想修改一个文件,而不是为每个用户指定很多文件。这就是我问的原因。

答案1

太长了;博士

运行ssh 127.0.0.1 ydisplay~/.bashrc而不是/etc/profile.改为更改您的路径~/.bashrc

细节

唯一/etc/profile被读取的时间是当您的 shell 是“登录 shell”时。

来自Bash 参考手册:

当 bash 作为登录 shell 被调用时,...它首先从文件 /etc/profile 中读取并执行命令

但是当您运行时ssh 127.0.0.1 ydisplaybash不会作为登录 shell 启动。但它确实读取了不同的启动文件。这Bash 参考手册说:

当...由...sshd执行时。 ...它读取并执行命令~/.bashrc

所以你应该把你的PATH设置放在~/.bashrc.

在大多数系统上,~/.bash_profilesources ~/.bashrc,因此您可以仅将设置放入~/.bashrc而不是将它们放入两个文件中。

没有标准方法可以更改所有用户的设置,但大多数系统都有/etc/bashrc/etc/bash.bashrc或类似的。

如果失败,请设置pam_env并将PATH设置放入/etc/environment.

也可以看看:

答案2

从历史上看,配置文件(/etc/profile~/.profile)在您登录(在文本控制台上,还有什么?)时被调用,并具有多种用途:

  • 设置会话的环境变量和其他参数(例如umask)。
  • 在会话开始时运行额外的程序(例如电子邮件通知)。
  • 如果与 shell 不同(例如另一个 shell 或 X Window),则运行会话的程序。
  • 设置终端参数(如stty)。
  • 设置 shell 参数(例如别名)。

直到后来,所有这些目的才被确定为单独的。因为配置文件脚本可能会执行仅在交互式会话(终端交互、启动其他程序)中有意义的操作,因此当远程 shell 调用时(rsh)引入后,rsh 的制作者决定不调用远程 shell 作为登录 shell,以便不执行配置文件脚本。 (某些版本rshd可以选择将远程 shell 作为登录 shell 运行。)ssh 复制了此行为,以便成为 rsh 的直接替代品。

如果您希望执行您的配置文件脚本,您可以显式调用它们。

ssh 127.0.0.1 '. /etc/profile; . ~/.profile; ydisplay'

.请注意在 shell 内加载配置文件脚本的命令:它们是在该 shell 内执行的命令,而不是外部程序。

如果要为所有用户全局设置环境变量,许多系统上还有另一种方法:不在 中定义/etc/profile,而是在 中定义/etc/environment。该文件是通过读取pam_env模块;大多数 Linux 发行版都设置为可以读取它。

如果您的登录 shell 是 bash,则还有进一步的可能性。通常情况下,你不应该设置环境变量.bashrc(因为除非您通过具有交互式 shell 的终端,否则它们不会在 X 会话中设置,因为如果您在文本控制台或通过 ssh 交互式登录,则不会设置它们,因为它们会覆盖自定义设置如果您在另一个程序中调用 shell)。然而,bash 有一个我从未理解过的奇怪功能:它~/.bashrc在两种不相关的情况下读取:

  • 在非登录 shell 的交互式 shell 中;
  • 在不是登录 shell 的非交互式 shell 中,如果 bash 认为它已被rshd或调用sshd

当您通过 ssh 运行命令时,您处于第二种情况。您可以安排通过阅读/etc/profile.profilefrom 来阅读您的个人资料.bashrc。在您的 中包含以下代码~/.bashrc

case $- in
  *i*) :;; # this is an interactive shell, fine
  *) # This is not an interactive shell! This must be a non-interactive remote shell session.
    . /etc/profile; . ~/.profile
    return;;
esac

答案3

我以前也遇到过这个问题。原因很简单,

如果两个可执行文件共享相同的名称,位于两个不同的目录中,则 shell 将运行 $PATH 中第一个目录中的文件

来源:如何在 Linux 中添加目录到 PATH

我有一个名为 Pointwise 的应用程序。当我检查其可执行文件的位置时,我注意到以下事情:

:~> which pointwise
/usr/local/bin/pointwise

这是空的,但安装创建了该目录。当我检查时$PATH,我有:

/usr/bin/path:/home/mendezj/bin:/usr/local/bin:/usr/bin:/bin:/opt/pbs/bin:/opt/sim_pkgs/working/apps/POINTWISE

请注意,我已更改/etc/profile并将实际路径附加到可执行文件。为了解决该问题,我更改了可执行文件的位置。我把它带到变量的开头$PATH

它是:

PATH="$PATH:/opt/sim_pkgs/working/apps/POINTWISE"

我把它改为:

PATH="/opt/sim_pkgs/working/apps/POINTWISE:$PATH"

问题解决了,因为它在转到 之前先查看第一个条目/usr/local/bin

相关内容