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_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:
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_COMMAND
variabel:
PROMPT_COMMAND="isnewline"
Lihat hasilnya:
user@host:~$ true
user@host:~$ <return>
User hit return
user@host:~$ <space><return>
user@host:~$
last
dipertahankan dari satu permintaan isnewline
ke yang berikutnya (hanya memilih nama yang kurang umum seperti prompt_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
menjebak debug some_command_or_function
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.
(Ini akan menjadi komentar untuk jawaban yang diterima jika saya diizinkan untuk menambahkan komentar ...) @ schlimmen, Anda dapat mengatur HISTTIMEFORMAT
ke 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 HISSTIMEFORMAT
set yang tepat, history 1
akan menampilkan timestamp (tidak seperti fc
), dan dengan demikian berbeda bahkan antara perintah yang diulang.