GNU/Linux >> Belajar Linux >  >> Linux

Bisakah Bash Menulis Ke Aliran Inputnya Sendiri?

Apakah mungkin dalam bash interactive yang interaktif shell untuk memasukkan perintah yang mengeluarkan beberapa teks sehingga muncul pada prompt perintah berikutnya, seolah-olah pengguna telah mengetik teks itu pada prompt itu?

Saya ingin dapat source skrip yang akan menghasilkan baris perintah dan mengeluarkannya sehingga muncul saat prompt kembali setelah skrip berakhir sehingga pengguna dapat mengeditnya secara opsional sebelum menekan enter untuk mengeksekusinya.

Ini dapat dicapai dengan xdotool tapi itu hanya berfungsi saat terminal berada di jendela X dan hanya jika sudah terpasang.

[[email protected]] 100 $ xdotool type "ls -l"
[[email protected]] 101 $ ls -l  <--- cursor appears here!

Dapatkah ini dilakukan hanya dengan menggunakan bash?

Jawaban yang Diterima:

Dengan zsh , Anda dapat menggunakan print -z untuk menempatkan beberapa teks ke dalam buffer editor baris untuk perintah berikutnya:

print -z echo test

akan mengungguli editor baris dengan echo test yang dapat Anda edit pada prompt berikutnya.

Saya tidak berpikir bash memiliki fitur serupa, namun pada banyak sistem, Anda dapat melakukan prime buffer input perangkat terminal dengan TIOCSTI ioctl() :

perl -e 'require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_)
  for split "", join " ", @ARGV' echo test

Akan menyisipkan echo test ke dalam buffer input perangkat terminal, seolah-olah diterima dari terminal.

Variasi yang lebih portabel pada Terminology @mike pendekatan dan itu tidak mengorbankan keamanan akan mengirim emulator terminal query status report yang cukup standar urutan pelarian:<ESC>[5n terminal mana yang selalu membalas (sebagai masukan) sebagai <ESC>[0n dan ikat itu ke string yang ingin Anda masukkan:

bind '"e[0n": "echo test"'; printf 'e[5n'

Jika dalam screen GNU , Anda juga dapat melakukan:

screen -X stuff 'echo test'

Sekarang, kecuali untuk pendekatan ioctl TIOCSTI, kami meminta emulator terminal untuk mengirimi kami beberapa string seolah-olah diketik. Jika string itu muncul sebelum readline (bash editor baris) telah menonaktifkan gema lokal terminal, maka string itu akan ditampilkan bukan pada prompt shell, mengacaukan tampilan sedikit.

Untuk mengatasinya, Anda dapat menunda pengiriman permintaan ke terminal sedikit untuk memastikan respons tiba saat gema dinonaktifkan oleh readline.

bind '"e[0n": "echo test"'; ((sleep 0.05;  printf 'e[5n') &)

(di sini dengan asumsi Anda sleep mendukung resolusi sub-detik).

Terkait:Slash dan backslash di sed?

Idealnya Anda ingin melakukan sesuatu seperti:

bind '"e[0n": "echo test"'
stty -echo
printf 'e[5n'
wait-until-the-response-arrives
stty echo

Namun bash (berlawanan dengan zsh ) tidak memiliki dukungan untuk wait-until-the-response-arrives seperti itu yang tidak membaca tanggapannya.

Namun ia memiliki has-the-response-arrived-yet fitur dengan read -t0 :

bind '"e[0n": "echo test"'
saved_settings=$(stty -g)
stty -echo -icanon min 1 time 0
printf 'e[5n'
until read -t0; do
  sleep 0.02
done
stty "$saved_settings"

Bacaan lebih lanjut

Lihat jawaban @starfry yang memperluas dua solusi yang diberikan oleh @mikeserv dan saya sendiri dengan beberapa informasi lebih detail.


Linux
  1. Bisakah Skrip Bash Dihubungkan ke File?

  2. Bagaimana saya bisa menulis skrip bash Linux yang memberi tahu saya komputer mana yang AKTIF di LAN saya?

  3. Bash/sh pernyataan 'jika lain'

  1. Skrip Bash Shell - Periksa bendera dan ambil nilainya

  2. dapatkah suatu program membaca bagian elfnya sendiri?

  3. Apa gunanya $# di Bash

  1. Cara menulis loop di Bash

  2. Terminal mana yang lebih baik:Bash vs Zsh

  3. Bagaimana saya bisa mendapatkan nomor terakhir dari string di bash?