PROMPT_COMMANDの最後のコマンドが空であることを確認する

PROMPT_COMMANDの最後のコマンドが空であることを確認する

BashのPROMPT_COMMAND内で、ユーザーがコマンドを入力せずに「return」を押したかどうかを知る方法はありますか?

答え1

履歴番号が増加していることを確認してください。キャンセルされたプロンプトまたはユーザーが押したばかりのプロンプトはEnter履歴番号を増やしません。

履歴番号は変数で使用できますが、HISTCMD使用できませんPROMPT_COMMAND(必要なのは実際には前のコマンドの履歴番号であり、PROMPT_COMMAND自己実行コマンドには履歴番号がないためです)。の出力から数字を得ることができます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'

履歴に重複圧縮が設定されている場合(HISTCONTROL=ignoredupsまたはHISTCONTROL=erasedups)、2つの同じコマンドが連続して実行された後、空のコマンドが誤って報告されます。

答え2

回避策がありますが、いくつかの要件があります。

$HISTCONTROL重複、スペースを含むすべてのコマンドを保存するには設定が必要です。したがって、設定:

HISTCONTROL=

ここで呼び出す関数を定義します$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"
}

ここで$PROMPT_COMMAND変数を設定します。

PROMPT_COMMAND="isnewline"

出力を表示します。

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

答え3

私はこれを行う方法がわからないそれ自体。しかし、以下を使用すると同じ効果が得られます。

一部のコマンドまたは機能デバッグ

これによりsome_command_or_functionコマンドが実行されるたびに呼び出されます。難しいのは、単にクリックすると呼び出されないことです。 PROMPT_COMMANDを定義しない限り呼び出されませんEnter。この場合、クリックはEnterPROMPT_COMMAND を呼び出してトラップをトリガします。

おそらく望ましい結果を得る最も簡単な方法は、PROMPT_COMMANDを使用する代わりにデバッグトラップ関数を定義することです。しかし、あなたが望む結果が何であるかわからないので言うことはできません。クリックすると何かが起こりEnter、コマンドを入力したときに別の/追加が起こるようにするには(AFAIK)デバッグトラップとPROMPT_COMMANDを使用する必要があります。バラよりこの回答そして これ これら2つのメカニズムが一緒にうまく機能する方法を探しています。

答え4

(コメントを追加できたら、許可された回答へのコメントになります...)@schlimmen、HISTTIMEFORMAT同様のものに設定HISTTIMEFORMAT='%F %T 'して保存して比較できますhistory 1。これは、削除を使用すると、少なくとも(繰り返し可能な)最後のコマンドのタイムスタンプが毎回変更されるためです。HISSTIMEFORMAT適切な設定を使用するとhistory 1タイムスタンプが表示される(とは異なりますfc)、繰り返されるコマンド間でも異なります。

関連情報