Saya memiliki bash
jendela terminal tempat saya mengeksekusi satu perintah secara eksklusiffoo
. Karena itu saya ingin setiap baris (setelah prompt tentu saja) dimulai dengan "foo" sehingga saya hanya perlu mengetikkan opsi dan argumen fungsi, tetapi bukan nama fungsi berulang. Tentu saja akan menyenangkan untuk dapat mengubah string yang dimasukkan secara otomatis juga, tetapi itu tidak penting bagi saya.
Contoh
Ketika saya membuka terminal, tanpa mengetik apa pun yang ingin saya lihat adalah:
user@host:~/ $ foo
Kemudian saya mengetik --option argument
dan ketika saya menekan Enterfungsi foo
dipanggil dengan yang diberikan --option
dan argument
.
Apa yang saya coba
Saya mencoba untuk bermain-main dengan $PS1
dan $PROMPT_COMMAND
menggunakan xdotool type "foo "
dan mengherankan yang benar-benar berfungsi, tetapi sayangnya itu juga mencetak "foo" sebelum prompt, yang cukup jelek:
user@host:~/ $ PROMPT_COMMAND='xdotool type "foo "'
foo user@host:~/ $ foo
Saya juga menemukan dan mencoba preexec
fungsi dari script bash-preexec Ryan Caloras , tetapi memiliki masalah yang persis sama.
Bagaimana cara menggaungkan (a (executable-) string) ke prompt, sehingga kursor berkedip di akhir baris? terkait, tetapi jawaban di sana tidak memungkinkan untuk menambahkan sesuatu ( --option argument
) ke perintah yang akan dieksekusi. Tapi saya tidak menguji zsh
- harus ada bash
solusi untuk hal sederhana seperti itu, bukan begitu?
sumber
expect
, tetapi tidak memasukkan teks pada setiap prompt, tetapi hanya pada yang pertama. Sementara itu ingin di pertanyaan terkait, tujuan saya berbeda.Jawaban:
Dengan
zsh
, seharusnya hanya masalah:Atau untuk menghindarinya mengesampingkan perintah yang antri oleh pengguna dengan Alt+q:
Dengan
bash
, alih-alihxdotool
, Anda dapat menggunakanTIOCSTI
ioctl
:Lebih disukai
xdotool
karena menyisipkan karakter-karakter tersebut secara langsung ke buffer input perangkatbash
.xdotool
hanya akan berfungsi jika ada server X yang berjalan (tidak akan berfungsi pada konsol atau terminal nyata atau lebihssh
(tanpa-X
) misalnya), bahwa itu adalah yang diidentifikasi oleh$DISPLAY
dan itulah yang Anda berinteraksi dengan, dan bahwa terminal emulator yangbash
sedang berjalan memiliki fokus ketika$PROMPT_COMMAND
dievaluasi.Sekarang, seperti pada Anda
xdotool
hal, karenaioctl()
dilakukan sebelum prompt ditampilkan dan tty garis terminal disiplin menempatkan keluar dariicanon+echo
modus dengan readline, Anda cenderung melihat gema dari yangfoo
oleh disiplin baris tty mengacaukan layar.Anda dapat mengatasinya dengan memasukkan string yang gema- nya tidak terlihat (seperti U + 200B jika menggunakan lokal Unicode secara eksklusif) dan mengikatnya ke tindakan yang memasukkan
"foo "
:Atau Anda dapat menunda
TIOCSTI
cukup ioctl agar readline punya waktu untuk menginisialisasi:Jika, seperti dalam
zsh
pendekatan, Anda ingin menangani kasus di mana pengguna memasukkan teks sebelum prompt ditampilkan, Anda bisa melakukannyatcflush(0, TCIFLUSH)
inperl
sebelumTIOCSTI
ioctl (juga perlu-MPOSIX
opsi), atauseperti dalam
zsh
pendekatan, pastikanfoo
dimasukkan pada awal buffer dengan memasukkan^A
(dengan asumsi Anda menggunakanemacs
mode pengeditan (default) di mana yang memindahkan kursor ke awal baris) sebelumfoo
dan^E
sesudah (untuk pindah ke akhir) :atau
sumber
insert
Fungsi membutuhkan sedikit pekerjaan untuk benar mengutip argumen yang memerlukan mengutip. Mungkin denganperl ... -- "$(printf "%q " "$@")"
foo
atau karakter U + 200B, bukan'foo '
foo "bar baz"
mana argumen ke-2 perlu dikutip.insert
di sini dimaksudkan untuk mendapatkan kode shell sebagai argumen (sepertieval
) sehingga Anda dapat menyebutnya denganinsert 'VAR="x y" cmd2 '
atauinsert 'cmd "${default_opt[@]}" '
misalnya yang tidak dapat Anda lakukan jikainsert
mengutip argumennya sendiri.Apa yang Anda minta tidak terdengar biasa sehingga tidak mengherankan bahwa tidak ada cara langsung untuk melakukannya.
Dengan bash murni, Anda bisa menggunakan
read
builtin untuk membaca baris, lalueval
untuk mengeksekusinya. Simulasikan bisikan (Saya mendekati bisikan Anda di bawah).Masukkan ini ke dalam skrip dan beri tahu emulator terminal Anda untuk menjalankan skrip itu.
Atau, jalankan Screen di terminal emulator. Anda dapat menggunakan
stuff
perintahnya untuk mensimulasikan input.sumber