Comandos SSH remotos - aviso de ligação bash: edição de linha não habilitada

Comandos SSH remotos - aviso de ligação bash: edição de linha não habilitada

Estou usando o bash 4.3.11(1) e tenho o seguinte plugin de histórico instalado (via.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'

Quando faço login em uma sessão interativa, tudo está bem, mas quando executo comandos remotos, ssh host 'ls -als'por exemplo, vejo a seguinte saída:

: 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

Quando modifico o plugin de histórico echo -e '\0033\0143'após cada chamada de ligação, não recebo mais os avisos, mas meu console é limpo. Não é uma grande desvantagem, mas seria bom conhecer uma maneira mais limpa de suprimir isso para comandos remotos.

# 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'

Responder1

Ter uma sessão interativa não é suficiente para bindfuncionar. Por exemplo, o shell do emacs fornece uma sessão interativa que passa no if [ -t 1 ]teste, mas não possui a edição de linha, portanto, qualquer binds no seu ~/.bashrcgerará os avisos. Em vez disso, você pode verificar se a edição de linha está habilitada fazendo algo assim (existe uma maneira mais simples/melhor?):

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

Responder2

ssh host 'ls -als'

Quando você pede ao ssh para executar um comando no sistema remoto, o ssh normalmente não aloca um PTY (pseudo-TTY) para a sessão remota. Você pode executar ssh para -tforçá-lo a alocar um tty:

ssh -t host 'ls -als'

Se não quiser digitar isso o tempo todo, você pode adicionar esta linha ao arquivo ".ssh/config" em seu host local:

RequestTTY yes

Como alternativa, você pode corrigir o arquivo “.bashrc” em seu sistema remoto para evitar a execução de comandos que presumem que a sessão é interativa, quando na verdade não é. Uma maneira é incluir os comandos em um teste de que a sessão possui um TTY:

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

Responder3

Se não houver edição de linha, esses bindcomandos serão inofensivos. Suprima os avisos:

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

Isso é um tanto deselegante, mas ainda assim deve funcionar. Outras respostas não concordam sobre o teste melhor/suficiente. Minha abordagem contorna isso. Porém, não é bem dimensionado. Os dois comandos por si só não deveriam fazer grande diferença; mas se você tivesse mais, como dezenas, então uma condicional adequada provavelmente seria melhor.

Responder4

Eu provavelmente testaria se meu bash é interativo.

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

informação relacionada