Masalah saya adalah bahwa Bash shell berhenti menampilkan karakter yang saya ketik di dalamnya. Itu membaca perintah sekalipun.
Saya telah menemukan masalah ini beberapa kali dan saya tidak mengerti apa penyebabnya. Saya tahu bagaimana menyelesaikannya, tapi saya benar-benar tidak suka ketika saya "voodooing" cara saya keluar dari masalah.
Saya akan menjelaskan dua cara saya menemukan masalah ini:
Saya sedang menjalankan proses tertentu, http://pythonpaste.org/script/ dan kadang-kadang ketika saya menghentikannya atau kontrol rusak diberikan kembali ke shell. Ketika saya kemudian pergi dan mengetik perintah ke shell, karakter yang saya ketik tidak muncul. Ketika saya tekan enter perintah yang disampaikan. Jadi misalnya:
- Saya mengetik "ls"
- Saya hanya melihat prompt kosong dan tidak lebih
- Aku tekan enter dan aku diberi daftar dari file, dengan kata lain: perintah yang dieksekusi
- ketika saya memberikan perintah "reset" shell mulai bekerja secara normal lagi
Cara kedua ini terjadi adalah ketika saya memberi perintah seperti ini:
$ grep foo * -l | xargs vim
Saya menggunakan grep untuk menemukan file yang memiliki pola tertentu dan kemudian saya ingin membuka semua file yang dihasilkan dari grep. Ini berfungsi seperti pesona (meskipun tidak secepat yang saya harapkan). Tetapi ketika saya keluar dari Vim, shell saya berhenti menunjukkan karakter yang saya ketik. Perintah reset menyelesaikan masalah.
Dugaan saya adalah bahwa kedua masalah memiliki alasan mendasar, tapi saya agak bingung bagaimana atau apa alasannya.
Mencari masalah ini sendiri bermasalah karena uraiannya agak kabur dan tidak memiliki istilah pencarian yang sulit untuk itu.
Sunting
Memberi
stty --all
perintah sesuai permintaan John S. Gruber memberikan output berikut (spasi putih diedit untuk dibaca)
speed 0 baud;
rows 53;
columns 186;
line = 0;
intr = <undef>;
quit = <undef>;
erase = <undef>;
kill = <undef>;
eof = <undef>;
eol = <undef>;
eol2 = <undef>;
swtch = <undef>;
start = <undef>;
stop = <undef>;
susp = <undef>;
rprnt = <undef>;
werase = <undef>;
lnext = <undef>;
flush = <undef>;
min = 0;
time = 0;
-parenb
-parodd cs8
-hupcl
-cstopb cread
-clocal
-crtscts
-ignbrk
-brkint
-ignpar
-parmrk
-inpck
-istrip
-inlcr
-igncr
-icrnl
-ixon
-ixoff
-iuclc
-ixany
-imaxbel
-iutf8
-opost
-olcuc
-ocrnl
-onlcr
-onocr
-onlret
-ofill
-ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig
-icanon
-iexten
-echo
-echoe
-echok
-echonl
-noflsh
-xcase
-tostop
-echoprt
-echoctl
-echoke
sumber
stty --all
dan masukkan hasilnya dalam pertanyaan Anda. Echo adalah karakteristik tty yang dimatikan. Vim akan melakukan ini ketika sedang berjalan, dan itu akan menempatkan terminal dalam mode mentah juga. Ketika berhenti, seharusnya me-reset pengaturan terminal itu sendiri. Ketika vim sedang berjalan Anda tidak ingin mengulangii
perintah yang menempatkan editor ke mode penyisipan, misalnya. Pengaturan ini memberi tahu perangkat tty bagaimana seharusnya memproses apa yang Anda ketik. Sementara vim sedang berjalan, ia tetap memperhatikan apa yang harus digaungkan, dll.stty --all
ke pertanyaan saya. Terima kasih sebelumnya!Jawaban:
Saat menjalankan shell atau sebagian besar program di shell, apa pun yang Anda ketikkan akan kembali ke terminal pengguna oleh subsistem tty kernel. Ada penanganan khusus lainnya, juga untuk menghapus karakter, Ctrl + R, Ctrl + Z, dan sebagainya.
Program tertentu, (khususnya editor) yang dijalankan dari baris perintah tidak memerlukan atau menginginkan ini. Karena alasan ini mereka memberi sinyal kernel dengan panggilan IOCTL terhadap perangkat tty (terminal) yang tidak mereka inginkan perilaku ini. Mereka juga tidak ingin karakter khusus melakukan hal-hal khusus. Sebagai gantinya mereka meminta kernel untuk mode "mentah". Secara khusus, vim seperti editor mematikan berbagai "pengaturan gema". Semua ini berlaku untuk terminal tty nyata pada garis serial komputer, atau terminal virtual di Alt + Ctrl + F1, atau terminal benar-benar virtual yang Anda dapatkan ketika Anda menjalankan sesuatu seperti terminal gnome di bawah GUI.
Program semacam itu seharusnya mengatur ulang mode apa pun yang mereka ubah pada virtual tty yang mereka gunakan sebelum berhenti, baik dengan memasukkan perintah editor berhenti atau dengan mengambil sinyal (dari Kontrol + C) misalnya.
Jika mereka gagal melakukan ini dengan benar tty dibiarkan dalam keadaan lucu yang telah Anda temukan. Karena program dapat gagal untuk mereset terminal,
reset
perintah ditulis untuk memungkinkan pengguna untuk pulih.Saya berasumsi interruptnya mengacaukan perangkat lunak python yang sedang Anda jalankan. Saya kira program itu tidak mendapatkan kesempatan untuk mengatur ulang terminal, atau gagal melakukannya.
Dalam kasus vim, ketika saya menjalankan contoh Anda, saya mendapatkan perilaku yang sama seperti yang Anda gambarkan. Saya juga melihat pesan "Vim: Peringatan: Input bukan dari terminal" (Itu hilang saat Anda mereset). Ini karena vim tidak dimulai secara normal dari shell. Alih-alih perintah 'grep' dan 'xargs' telah menggunakan input standar, biasanya ditempati oleh tty, untuk keperluan menyampaikan nama file dari
grep
ttoxargs
.Dalam output yang Anda posting dari
stty -a
kita dapat melihat "-echo", juga mengkonfirmasi bahwa ini adalah masalahnya. Jika Anda membunuh vim sedemikian rupa sehingga tidak bisa menangani sinyal dengan anggun Anda mungkin akan melihat masalah yang sama.Masalahnya dijelaskan di tempat lain di https://stackoverflow.com/questions/3852616/xargs-with-command-that-open-editor-leaves-shell-in-weird-state .
Solusi untuk vim case adalah menghindari xargs dan gunakan sebagai gantinya:
Di sini daftar file dibangun oleh shell, seperti yang dilakukan oleh xargs, tetapi shell memanggil vim, yang langsung terhubung ke tty. Ada pesan peringatan yang dikirim ke file output kesalahan, dan vim menetapkan dan mengatur ulang pengaturan tty dengan benar.
Lebih banyak referensi di sini , dan satu lagi yang menarik di sini . Solusi lain yang menarik diberikan dalam jawaban untuk https://stackoverflow.com/questions/8228831/why-does-locate-filename-xargs-vim-cause-strange-terminal-behaviour .
sumber
grep foo * -l | vim -
tanpa masalah. Jadi saya pikir masalahnya bukan dengan grep dan xargs, tetapi hanya dengan xargs. Apakah kamu setuju?git add -p
!Saya akan memulai pengguna baru di sistem (maksud saya membuat pengguna bersih baru dan login di sana), dan melihat apakah masalahnya ada di sana. Jika tidak - maka itu adalah terminal Anda atau pengaturan X11 Anda.
sumber
grep foo * -l | xargs vim
perintah. Masalahnya masih ada. Saya tidak mengerti persis bagaimana pengaturan X11 saya dapat mempengaruhi bagaimana terminal saya bereaksi btw. Bisakah Anda menguraikan itu? Terima kasih!