PROMPT_COMMAND uygulamasında son komutun boş olup olmadığını söyle


12

Bash'da, PROMPT_COMMAND'ın içinden, kullanıcının 'return' tuşuna basıp basmadığını bir komut girip girmediğini anlamanın bir yolu var mı?

Yanıtlar:


7

Geçmiş numarasının artırılıp artırılmadığını kontrol edin. İptal edilen bir bilgi istemi veya kullanıcının henüz bastığı bir bilgi istemi Entergeçmiş numarasını artırmaz.

Geçmiş numarası değişkente kullanılabilir HISTCMD, ancak bu burada kullanılamaz PROMPT_COMMAND(çünkü istediğiniz şey aslında önceki komutun geçmiş numarasıdır; PROMPT_COMMANDkendini yürüten komutun geçmiş numarası yoktur). Sayıyı çıktısından alabilirsiniz 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'

Geçmişte ( HISTCONTROL=ignoredupsveya HISTCONTROL=erasedups) yinelenenleri ezmeyi etkinleştirdiyseniz , bu işlem iki özdeş komutu art arda çalıştırdıktan sonra yanlışlıkla boş bir komut bildireceğini unutmayın.


Teşekkürler, Gilles. Burada bir şey eksik. PROMPT_COMMAND = 'echo hello' olsa da, değişmez işlevin ilk satırına 'echo hello' koymak işe yaramadığı için bu asla çalışmaz. HISTCMD_previous vs HISTCMD_PREVIOUS sorunu olabileceğini düşündüm, ancak zar yok. Alay etmeye devam edeceğim, ama bash fu'nuzun benimkinin ötesinde açıkça ligler olduğu için yorum yapıyorum.
kullanıcı

@ kullanıcı Ben daha fazla yazım hataları düzeltti, özellikle ${HISTCMD_previous%%$'[\t ]'*}bit eksikti $'…'ve `, sekme veya boşluk yerine t` veya boşluk sonra kesilmiş , ancak bash bir sekme yazdırır.
Gilles 'SO- kötü olmayı bırak'

1
Bu çözüm, kopyaların geçmişe kaydedildiği varsayımına dayanmaktadır (ki bu benim için KAPALI). Bu nedenle, yinelemeler geçmişe kaydedilmezken bu çözüm tekrarlanan komutlar için beklendiği gibi çalışmaz.
schlimmchen

4

Bir çözüm var, ancak bazı gereksinimleri var:

$HISTCONTROLTÜM komutları, ayrıca kopyaları ve boşlukları kaydetmek için ayarlamanız gerekir . Öyleyse ayarlayın:

HISTCONTROL=

Şimdi çağrılacak bir fonksiyon tanımlayın $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"
}

Şimdi, $PROMPT_COMMANDdeğişkeni ayarlayın :

PROMPT_COMMAND="isnewline"

Çıktıya bakın:

user@host:~$ true
user@host:~$ <return>
User hit return
user@host:~$ <space><return>
user@host:~$ 

Burada neden geçici bir dosya kullandığınızı anlamıyorum. Değişken last, bir çağrısından diğerine çağrılır isnewline(yalnızca prompt_command__isnewline__lastçakışmalardan kaçınmak için daha az genel bir ad seçin ).
Gilles 'SO- kötü olmayı bırak'

@Gilles Haklısın, değiştirdim, önerin için teşekkürler
kaos

Teşekkürler kaos. Aynı fikri, ayrıştırmak için biraz daha kolay olan aşağıdaki için kullandım. 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
kullanıcı

1

Ben, bunu yapmak için bir yol bilmiyorum haddi zatında . Ama aynı etkiyi kullanarak

trap some_command_or_function hata ayıklama

Bu, some_command_or_functionbir komutu her çalıştırdığınızda çağrılmasına neden olur . Zor olan şey, sadece vurursanız çağrılmayacaktır Enter- bir PROMPT_COMMAND tanımlı değilseniz, bu durumda vurmak EnterPROMPT_COMMAND'ı çağırır ve bu da tuzağı tetikler.

Belki de istediğiniz sonucu elde etmenin en basit yolu bir PROMPT_COMMAND kullanmak yerine bir hata ayıklama tuzağı işlevi tanımlamaktır. Ama söyleyemem, çünkü hangi sonucu istediğini bilmiyorum. Sadece vurduğunuzda bir Enterşey olmasını ve bir komut yazarken farklı / ek bir şey olmasını istiyorsanız, (AFAIK) bir hata ayıklama tuzağı ve bir PROMPT_COMMAND kullanmanız gerekir. Bkz bu cevabı ve  bu bir iki mekanizma birlikte güzel oynamak yapmak için bir yol.


0

(Yorum eklememe izin verilmiş olsaydım, bu kabul edilen cevaba bir yorum olurdu ...) @schlimmen, HISTTIMEFORMATbenzer bir şeye ayarlayabilir HISTTIMEFORMAT='%F %T 've sonra kaydedip karşılaştırabilirsiniz history 1. Çünkü silme işlemlerinde en azından (muhtemelen tekrarlanan) son komutun zaman damgası her seferinde değişir --- ve HISSTIMEFORMATuygun şekilde ayarlandığında, history 1zaman damgasını görüntüler (aksine fc) ve böylece tekrarlanan komutlar arasında bile farklılık gösterir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.