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).
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.