远程 SSH 命令 - bash bind 警告:未启用行编辑

远程 SSH 命令 - bash bind 警告:未启用行编辑

我正在使用 bash 4.3.11(1),并安装了以下历史插件(通过.bash_it):

# enter a few characters and press UpArrow/DownArrow
# to search backwards/forwards through the history
bind '"^[[A":history-search-backward'
bind '"^[[B":history-search-forward'

当我登录到交互式会话时一切正常,但是当我通过ssh host 'ls -als'例如运行远程命令时,我看到以下输出:

: ssh host 'ls -als'
/home/ubuntu/.bash_it/plugins/enabled/history.plugin.bash: line 3: bind: warning: line editing not enabled
/home/ubuntu/.bash_it/plugins/enabled/history.plugin.bash: line 4: bind: warning: line editing not enabled

当我在每次绑定调用后修改历史插件时,echo -e '\0033\0143'我不再收到警告,但我的控制台被清除了。这不是一个很大的缺点,但如果能知道一种更干净的方法来抑制远程命令的这种情况就好了。

# Works, but annoyingly clears console
# enter a few characters and press UpArrow/DownArrow
# to search backwards/forwards through the history
bind '"^[[A":history-search-backward'
echo -e '\0033\0143'
bind '"^[[B":history-search-forward'
echo -e '\0033\0143'

答案1

仅拥有交互式会话还不足以正常bind工作。例如,emacs shell 提供了一个通过if [ -t 1 ]测试的交互式会话,但它没有行编辑功能,因此bind您的任何 s~/.bashrc都会生成警告。相反,您可以通过执行以下操作来检查行编辑是否已启用(有没有更简单/更好的方法?):

if [[ "$(set -o | grep 'emacs\|\bvi\b' | cut -f2 | tr '\n' ':')" != 'off:off:' ]]; then
  echo "line editing is on"
fi

答案2

ssh host 'ls -als'

当您要求 ssh 在远程系统上运行命令时,ssh 通常不会为远程会话分配 PTY(伪 TTY)。您可以运行 ssh 来-t强制它分配 tty:

ssh -t host 'ls -als'

如果您不想一直输入这些内容,您可以将此行添加到本地主机上的“.ssh/config”文件中:

RequestTTY yes

或者,您可以修复远程系统上的“.bashrc”文件,以避免运行假定会话是交互式的命令,而实际上并非如此。一种方法是将命令包含在会话具有 TTY 的测试中:

if [ -t 1 ]
then
    # standard output is a tty
    # do interactive initialization
fi

答案3

如果没有行编辑,这些bind命令本身是无害的。抑制警告:

bind '"^[[A":history-search-backward' 2>/dev/null
bind '"^[[B":history-search-forward'  2>/dev/null

这有点不雅,但仍然应该有效。其他答案对最佳/充分测试意见不一。我的方法绕过了这一点。但它的可扩展性不好。这两个命令本身不应该产生很大的区别;但如果你有更多的命令,比如几十个,那么一个适当的条件可能会更好。

答案4

我可能只是想测试我的 bash 是否具有交互性。

if [[ "$-" = *i* ]]
then
    debug "interactive mode"
    source ~/.bash_lib/bindings
else
    debug "non interactive mode"
fi

相关内容