在特定主机上,当我 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
,并从第一个存在且可读的文件中读取并执行命令。