为什么“ssh host echo $PATH”和在 ssh 进入机器后打印 $PATH 会给出不同的结果?

为什么“ssh host echo $PATH”和在 ssh 进入机器后打印 $PATH 会给出不同的结果?

在特定主机上,当我 ssh 进入机器并输入时,echo $PATH我得到

/home/wxy/bin64:/home/wxy/bin:/usr/kerberos/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin

如果我执行ssh host 'echo $PATH'我会看到这个:

/usr/local/bin:/bin:/usr/bin

为什么会出现这样的差异呢?

另外,如果我想使用后一个命令查看前一个结果,我该怎么办?

答案1

在第一个场景中,您登录系统,因此您正在执行所谓的登录连接类型。登录会获取脚本$HOME/.bashrc$HOME/.bash_profile如果您是登录,则 shell 是 Bash。这两个脚本通常依次获取文件/etc/bashrc/etc/profile.d/*.sh.

对于第二种情况,您只需获取文件$HOME/.bashrc。这种类型的登录称为交互的

您可以在以下位置阅读有关这些内容的更多信息召唤的部分bash 手册页

要更改此行为,您可以将 $HOME/.bashrc_profile 作为交互式执行的一部分包含在内,以获得所需的行为:

$ ssh user@remotehost '. $HOME/.bash_profile; echo $PATH'

-或者-

$ ssh user@remotehost 'source $HOME/.bash_profile; echo $PATH'

参考

答案2

由于歇斯底里的历史原因,会话初始化文件很奇怪。

很久以前,您登录了控制台。当你登录时,你会得到一个 shell,shell 会加载一些初始化文件。对于 Bourne 风格的 shell,有两个初始化文件:(/etc/profile对于所有用户)和~/.profile(对于每个用户)。初始化文件可以设置环境变量如PATH,加载要在每个会话中运行的应用程序(例如邮件指示器)等。如果 shell 不是登录外壳,它不需要启动任何东西或设置环境变量,因此不需要运行任何初始化文件。肯定没有……

实际上,shell逐渐获得了交互功能,因此需要一个交互shell的初始化文件。 Ksh 有~/.kshrc,bash 有~/.bashrc,zsh 有~/.zshrc

远程交互式登录运行/etc/profile~/.profile。但这些不适合非交互式登录,因为它们可能会启动非交互式程序。不幸的是,还没有出现用于非交互式登录的初始化文件的标准。

如果您确定它们不会产生任何输出或启动任何程序,您可以手动运行/etc/profile,只需设置环境变量即可。~/.profile

ssh foo '. /etc/profile; . ~/.profile; somecommand'

如果您的某些部分.profile仅在交互式会话中有意义,您可以将它们放入条件指令中。

## (in ~/.profile)
case $- in
  *i*) # the shell is interactive
    newmail;;
esac

如果您的登录 shell 是 bash,则可以利用一个怪癖:初始化文件~/.bashrc由交互式 shell 以及父进程称为rshd或 的非交互式 shell 读取sshd。其他 shell 没有这个怪癖。

## (in ~/.bashrc)
case $- in
  *i*) # interactive shell: set prompt, completion settings, key bindings, etc.
    …;;
  *) # non-interactive shell: our parent must be rshd or sshd
    . ~/.profile;;
esac

答案3

如果您使用的是 bash,请检查/etc/profile主机是否无法获得预期的输出。请注意,bash 首先从该文件读取并执行命令/etc/profile(如果该文件存在)。读取该文件后,它会按顺序查找~/.bash_profile~/.bash_login、 和~/.profile,并从第一个存在且可读的文件中读取并执行命令。

相关内容