我正在使用 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