Jawaban:
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_COMMANDsendiri 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=ignoredupsatau 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 $HISTCONTROLuntuk menyimpan SEMUA perintah, juga duplikat dan spasi. Jadi atur:
HISTCONTROL=
Sekarang tentukan fungsi untuk memanggil sebagai $PROMPT_COMMAND:
isnewline () {
# read the last history number
prompt_command__isnewline__last="$prompt_command__isnewline__curr"
# get the current history number
prompt_command__isnewline__curr="$(history 1 | grep -oP '^\ +\K[0-9]+')"
[ "$prompt_command__isnewline__curr" = "$prompt_command__isnewline__last" ] && \
echo "User hit return"
}
Sekarang, atur $PROMPT_COMMANDvariabel:
PROMPT_COMMAND="isnewline"
Lihat hasilnya:
user@host:~$ true
user@host:~$ <return>
User hit return
user@host:~$ <space><return>
user@host:~$
lastdipertahankan dari satu permintaan isnewlineke yang berikutnya (hanya memilih nama yang kurang umum seperti prompt_command__isnewline__lastuntuk 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
menjebak debug some_command_or_function
Ini akan menyebabkan some_command_or_functiondipanggil 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.
(Ini akan menjadi komentar untuk jawaban yang diterima jika saya diizinkan untuk menambahkan komentar ...) @ schlimmen, Anda dapat mengatur HISTTIMEFORMATke sesuatu seperti HISTTIMEFORMAT='%F %T 'dan kemudian menyimpan dan membandingkan history 1. Itu karena dengan menghapus setidaknya timestamp dari (terakhir mungkin) perintah terakhir berubah setiap kali --- dan dengan HISSTIMEFORMATset yang tepat, history 1akan menampilkan timestamp (tidak seperti fc), dan dengan demikian berbeda bahkan antara perintah yang diulang.