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


9

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

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
只是在ydisplay工作吗?做ssh 127.0.0.1 /usr/app/cpn/bin/ydisplay工作?
Bananguin 2012年

@ user1129682是的,具有完整指定名称的ydisplay可以正常工作,而ydisplay可以正常工作
SIGSEGV

如果未登录(没有远程会话),而仅远程发送命令,则您将无法以相同的方式访问环境变量,因为不会执行.bashrc / .profile文件。这是原因,因为它们负责为当前会话设置变量。
mnmnc

14
附带说明:ssh 127.0.0.1 echo $PATH不会做您可能会想到的事情:甚至在ssh执行之前,shell都会扩展$ PATH,因此不会证明或否定任何东西。
Ulrich Schwarz

2
这个stackoverflow问题可能会有所帮助
2012年

Answers:


5

tl; dr

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

细节

唯一/etc/profile的读取时间是您的外壳是“登录外壳”时。

Bash参考手册

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

但是当您运行时ssh 127.0.0.1 ydisplaybash不会作为登录shell启动。但是它确实读取了另一个启动文件。该猛砸参考手册说:

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

因此,您应该将PATH设置输入~/.bashrc

在大多数系统上,它们是~/.bash_profilesource ~/.bashrc,因此您只能将设置~/.bashrc放入其中,而不能将其放入两个文件中。

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

失败的话,进行设置pam_env并将其放入PATH/etc/environment

也可以看看:


1

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

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

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

如果要执行配置文件脚本,则可以显式调用它们。

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

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

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

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

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

在ssh上运行命令时,您处于第二种情况。您可以通过阅读/etc/profile.profile从中安排阅读个人资料.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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.