最后.bashrc
我补充道:
touch /tmp/bash_noninteractive_test
跑步:
/usr/bin/ssh -v -C [email protected] 'ls'
在主机上(之前已交互登录):
% ls -l /tmp/bash_noninteractive_test
ls: cannot access /tmp/bash_noninteractive_test: No such file or directory
我以为~./bashrc
总是通过非交互式 shell 获取数据,比如通过 SSH?我该如何解决这个问题?
受影响的系统:
% lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty
% lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.11 (jessie)
Release: 8.11
Codename: jessie
答案1
我将我的一些信息添加到旧线程中,因为接受的答案不是 .bashrc 未被 ssh 命令读取的真正原因。我读完后得到了提示这个答案。bash 手册页中 INVOCATION 部分的倒数第二段指出:
Bash 尝试确定何时将其标准输入连接到网络连接来运行,例如由远程 shell 守护程序(通常是 rshd)或安全 shell 守护程序 sshd 执行时。如果 bash 确定它以这种方式运行,它会从 ~/.bashrc 和 ~/.bashrc 读取并执行命令(如果这些文件存在且可读)。如果以 sh 调用,它不会执行此操作。可以使用 --norc 选项来禁止此行为,可以使用 --rcfile 选项来强制读取另一个文件,但 rshd 和 sshd 通常都不会使用这些选项来调用 shell 或允许指定它们。
因此,尽管 ssh 命令以非交互式用户身份运行,但 .bashrc 仍会被加载。
但是你的操作系统可能会在 .bashrc 的顶部添加类似于以下内容的检查(来自 Ubuntu 18.04),它会在前几行之后退出 .bashrc 以进行非交互式调用。
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
为了阻止检查,请打开 .bashrc 并注释掉那些行,然后您的 ssh 命令将读取整个 .bashrc,我想这就是您所期望的结果。
答案2
摘自 的 INVOCATION 章节man bash
:
当启动非登录 shell 的交互式 shell 时,如果这些文件存在,bash 将从 和 读取并执行命令
/etc/bash.bashrc
。~/.bashrc
可以使用--norc
选项禁止此操作。file选项将强制 bash 从 file 而不是和--rcfile
读取并执行命令。/etc/bash.bashrc
~/.bashrc
例如,当以非交互方式启动 bash 以运行 shell 脚本时,它会
BASH_ENV
在环境中查找变量,如果变量出现则扩展其值,并使用扩展的值作为要读取和执行的文件的名称。Bash 的行为就像执行了以下命令一样:if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
但 PATH 变量的值不用于搜索文件名。
~/.bashrc
因此看起来绝不源自非交互式 shell,除非BASH_ENV
指向它。
根据您实际想要实现的目标,您可以考虑在远程主机上启用和/PermitUserRC
或,然后在和/或所需的命令中写入所需的环境变量。PermitUserEnvironment
/etc/ssh/sshd_config
~/.ssh/environment
~/.ssh/rc
笔记:如果您计划将 SSH X11 转发与一起使用~/.ssh/rc
,则必须包含一段代码以明确将 X11 会话提供给命令xauth -q -
;请参阅手册页的 SSHRC 章节中的示例sshd(8)
。