Dalam bash, dari dalam PROMPT_COMMAND, apakah ada cara untuk mengetahui apakah pengguna cukup menekan 'kembali' dan tidak memasukkan perintah?
12
Periksa apakah nomor riwayat bertambah. Permintaan yang dibatalkan atau permintaan di mana pengguna hanya menekan Entertidak akan menambah nomor riwayat.
Nomor sejarah tersedia dalam variabel HISTCMD
, tetapi ini tidak tersedia di PROMPT_COMMAND
(karena apa yang Anda inginkan sebenarnya ada nomor sejarah dari perintah sebelumnya; perintah yang mengeksekusi PROMPT_COMMAND
sendiri tidak memiliki nomor sejarah). Anda bisa mendapatkan nomor dari output fc
.
prompt_command () {
HISTCMD_previous=$(fc -l -1); HISTCMD_previous=${HISTCMD_previous%%$'[\t ]'*}
if [[ -z $HISTCMD_before_last ]]; then
# initial prompt
elif [[ $HISTCMD_before_last = "$HISTCMD_previous" ]]; then
# cancelled prompt
else
# a command was run
fi
HISTCMD_before_last=$HISTCMD_previous
}
PROMPT_COMMAND='prompt_command'
Perhatikan bahwa jika Anda telah mengaktifkan pemerasan duplikat dalam riwayat ( HISTCONTROL=ignoredups
atau HISTCONTROL=erasedups
), ini akan keliru melaporkan perintah kosong setelah menjalankan dua perintah yang identik secara berturut-turut.
${HISTCMD_previous%%$'[\t ]'*}
bit tidak ada$'…'
dan berakhir memotong setelah`,
t` atau spasi alih-alih tab atau spasi setelah, tetapi bash mencetak tab.Ada solusi, tetapi memiliki beberapa persyaratan:
Anda perlu mengatur
$HISTCONTROL
untuk menyimpan SEMUA perintah, juga duplikat dan spasi. Jadi atur:Sekarang tentukan fungsi untuk memanggil sebagai
$PROMPT_COMMAND
:Sekarang, atur
$PROMPT_COMMAND
variabel:Lihat hasilnya:
sumber
last
dipertahankan dari satu permintaanisnewline
ke yang berikutnya (hanya memilih nama yang kurang umum sepertiprompt_command__isnewline__last
untuk menghindari bentrokan).HISTCONTROL="" function last_was_blank { local last_command="$(history 1)" if [[ "$last_was_blank_PREVIOUS_LINE" = "$last_command" ]] ; then echo "true" else echo "false" fi export last_was_blank_PREVIOUS_LINE="$last_command" } PROMPT_COMMAND=last_was_blank
Saya tidak tahu cara untuk melakukan itu, per se . Tetapi Anda bisa mendapatkan efek yang sama dengan menggunakan
Ini akan menyebabkan
some_command_or_function
dipanggil kapan saja Anda menjalankan perintah. Yang sulit adalah, itu tidak akan dipanggil jika Anda baru saja menekan Enter- kecuali jika Anda memiliki PROMPT_COMMAND yang ditentukan, dalam hal ini memukul akan Entermemanggil PROMPT_COMMAND, yang, pada gilirannya, memicu jebakan.Mungkin cara paling sederhana untuk mencapai hasil yang Anda inginkan adalah mendefinisikan fungsi perangkap debug alih-alih menggunakan PROMPT_COMMAND. Tapi saya tidak tahu, karena saya tidak tahu hasil apa yang Anda inginkan. Jika Anda ingin sesuatu terjadi ketika Anda menekan Enter, dan sesuatu yang berbeda / tambahan terjadi ketika Anda mengetik perintah, maka (AFAIK) Anda perlu menggunakan perangkap debug dan PROMPT_COMMAND. Lihat jawaban ini dan yang ini untuk cara membuat kedua mekanisme bermain bersama dengan baik.
sumber
(Ini akan menjadi komentar untuk jawaban yang diterima jika saya diizinkan untuk menambahkan komentar ...) @ schlimmen, Anda dapat mengatur
HISTTIMEFORMAT
ke sesuatu sepertiHISTTIMEFORMAT='%F %T '
dan kemudian menyimpan dan membandingkanhistory 1
. Itu karena dengan menghapus setidaknya timestamp dari (terakhir mungkin) perintah terakhir berubah setiap kali --- dan denganHISSTIMEFORMAT
set yang tepat,history 1
akan menampilkan timestamp (tidak sepertifc
), dan dengan demikian berbeda bahkan antara perintah yang diulang.sumber