Remote SSH Commands - bash bind warning: pengeditan baris tidak diaktifkan

17

Saya menggunakan bash 4.3.11 (1) dan memasang plugin riwayat berikut (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'

Ketika saya masuk ke sesi interaktif semuanya baik-baik saja tetapi ketika saya menjalankan perintah jarak jauh ssh host 'ls -als'misalnya, saya melihat output berikut:

: 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

Ketika saya memodifikasi plugin riwayat dengan echo -e '\0033\0143'setelah setiap panggilan mengikat saya tidak lagi mendapatkan peringatan tetapi konsol saya dihapus. Bukan kelemahan besar tetapi akan menyenangkan untuk mengetahui cara yang lebih bersih untuk menekan ini untuk perintah jarak jauh.

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

Jawaban:

28
ssh host 'ls -als'

Ketika Anda meminta ssh untuk menjalankan perintah pada sistem jarak jauh, ssh biasanya tidak mengalokasikan PTY (pseudo-TTY) untuk sesi jarak jauh. Anda dapat menjalankan ssh dengan -tuntuk memaksanya mengalokasikan tty:

ssh -t host 'ls -als'

Jika Anda tidak ingin mengetik itu sepanjang waktu, Anda bisa menambahkan baris ini ke file ".ssh / config" di host lokal Anda:

RequestTTY yes

Sebagai alternatif, Anda dapat memperbaiki file ".bashrc" pada sistem jarak jauh Anda untuk menghindari menjalankan perintah yang menganggap sesi bersifat interaktif saat tidak. Salah satu caranya adalah dengan melampirkan perintah dalam tes bahwa sesi memiliki TTY:

if [ -t 1 ]
then
    # standard output is a tty
    # do interactive initialization
fi
Kenster
sumber
1
Sebenarnya jawaban ini salah, lihat jawaban @ alexander-vorobiev di bawah ini.
Ahmed Masud
2

Memiliki sesi interaktif tidak cukup untuk bindbekerja. Misalnya shell emacs menyediakan sesi interaktif yang lulus if [ -t 1 ]tes tetapi tidak memiliki pengeditan baris sehingga semua yang ada binddi Anda ~/.bashrcakan menghasilkan peringatan. Sebagai gantinya, Anda dapat memeriksa apakah pengeditan baris diaktifkan dengan melakukan sesuatu seperti ini (apakah ada cara yang lebih sederhana / lebih baik?):

if [[ "$(set -o | grep 'emacs\|\bvi\b' | cut -f2 | tr '\n' ':')" != 'off:off:' ]]; then
  echo "line editing is on"
fi
Alexander Vorobiev
sumber
Ini seharusnya jawaban yang benar
Ahmed Masud
1
Cara yang lebih mudah adalah dengan menggunakan[[ ${SHELLOPTS} =~ (vi|emacs) ]] && echo 'line-editing on' || echo 'line-editing off'
Ahmed Masud
1

Masukkan perintah bind ke dalam pernyataan 'jika' yang memeriksa apakah sesi bash memungkinkan pengeditan baris:

if [[ ${SHELLOPTS} =~ (vi|emacs) ]]; then
    bind '"^[[A":history-search-backward'
    bind '"^[[B":history-search-forward'
fi
Jonathan Hartley
sumber
1

Jika tidak ada pengeditan baris, bindperintah ini sendiri tidak berbahaya. Menekan peringatan:

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

Ini agak tidak sopan, masih harus bekerja. Jawaban lain tidak setuju tentang tes terbaik / cukup. Pendekatan saya mengelak dari ini. Itu tidak skala dengan baik. Kedua perintah itu sendiri seharusnya tidak membuat perbedaan besar; tetapi jika Anda memiliki lebih banyak, seperti lusinan, maka persyaratan yang tepat mungkin akan lebih baik.

Kamil Maciorowski
sumber
Poin yang bagus. Dapatkan upvote. :-)
Jonathan Hartley