在我的 .bashrc 的顶部,它包含以下命令:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
我从未将其添加到我的 .bash.rc 中,因为我的 .bashrc 模板是由 Ubuntu 创建的。
据我所知,此命令是为了防止在远程 shell (rsh) 或安全 shell (ssh) 上获取 .bashrc 文件。如果我的 .bashrc 中有类似以下内容alias rm='rename'
,则上面的别名将无法在远程 shell 中工作。但是,如果我没有该命令,则别名将起作用。如果远程 shell 上未安装“rename”,则运行时rm
会抛出错误。因此,最终目的是通过阻止 .bashrc 文件的来源来防止意外行为。
所以这就是我感到困惑的地方。我完全删除了这个命令,在远程 shell 上看不到任何区别。我在测试之前获取了 .bashrc,甚至重新启动了我的系统,但我没有看到 ssh 出现意外行为(在本例中是我的 2 个服务器)。
我尝试了简单的测试,例如在 .bashrc 中创建 echo 函数并尝试在服务器上调用它。我得到的只是未找到命令:foo。
我能得出的唯一结论是,因为我的一台服务器有自己的 .bashrc,另一台服务器有 .zshrc,所以它们优先于我本地的 .bashrc,所以它永远不会来源。如果是这样的话,为什么我需要上面的命令呢?上述命令是否已经过时并且在 2022 年不再发挥作用?或者也许它确实有用,但仅适用于通过 ssh 进入没有 .bashrc、.zshrc 或类似文件的服务器的系统管理员。
总括:如果我只通过 ssh 连接到已经拥有自己的 .bashrc 或 .zshrc 文件的自己的服务器,我是否需要在 .bashrc 文件中添加此内容?
答案1
一个交互的shell 是 shell 显示提示符并让您输入命令的地方。
非交互式 shell 是您启动脚本的地方。
读6.2 Bash 启动文件在手册中查看 shell 启动时获取了哪些文件。
通常,您将东西放入
~/.profile
或者~/.bash_profile
您希望在登录时发生(设置环境变量、启动 ssh 代理;影响交互式 shell 以及您可能运行的其他程序的内容)~/.bashrc
您只想为交互式使用而设置的内容(别名、函数;使输入命令更简单的东西)
这是之间的区别
$ echo "$-"
himBCHs
并运行脚本
$ cat > myscript.sh
#!/usr/bin/env bash
echo "$-"
$ bash ./myscript.sh
hB
~/.bashrc
如果您需要脚本中的内容,则可以source ~/.bashrc
,但这可能会被问题中的 case 语句击败。更好的选择是告诉 bash 你希望它像交互式 shell 一样工作
$ bash -i ./myscript.sh
himBCH
答案2
男人巴什 说
An interactive shell is one started without non-option
arguments (unless -s is specified) and without the -c option
whose standard input and error are both connected to
terminals (as determined by isatty(3)), or one started with
the -i option. PS1 is set and $- includes i if bash is
interactive, allowing a shell script or a startup file to
test this state.
您刚刚显示的代码是一个测试,用于检查您的 shell 是否是交互式的,在这种情况下它将执行其余部分,.bashrc
否则它将忽略 init-shell 文件的其余部分。
答案3
TLDR:如果我只通过 ssh 连接到已经拥有自己的 .bashrc 或 .zshrc 文件的自己的服务器,我是否需要在 .bashrc 文件中添加此内容?
是也不是。
是的。您将需要它来确保文件传输命令scp
可以正常工作。请参考这个错误:https://bugzilla.redhat.com/show_bug.cgi?id=20527
echo
如果.bashrc 中有任何内容,scp
则会失败。
不。如果您可以确保文件传输正常工作并且从不通过非交互式 shell 运行命令,则在 .bashrc 中不需要它
答案4
这是我找到的最清晰的图片:
(抱歉,我丢失了图片的来源。如果您找到它,请告诉我)
如果你用来ssh remote
连接远程服务器,它将是一个登录交互式shell。
如果使用ssh remote echo 1
连接到远程服务器,它会运行一个登录非交互式 shell,并使用这个 shell 来运行echo 1
exec /bin/zsh
如果您使用在 内部运行之类的技巧~/.bash_profile
,并使用ssh remote
连接到该服务器,则 zsh 将作为非登录交互运行。
exec /bin/zsh
如果您使用在 内部运行之类的技巧~/.bash_profile
,并使用ssh remote echo 1
连接到该服务器,则 zsh 将作为非登录非交互式运行。