web-dev-qa-db-ja.com

バッシュ:「履歴番号」と「コマンド番号」

PS1変数を使用してシェルプロンプトをカスタマイズする方法をグーグルで調べているときに、使用できる特殊文字の表が表示されます。特に:

          \!     the history number of this command
          \#     the command number of this command

「履歴番号」はより一般的に使用されているようで、!523などのコマンドを使用して履歴からコマンドをやり直す方法を知っています。しかし、「コマンド番号」に同様の機能があるかどうかはわかりません。 PS1変数に\#を入れてみましたが、特定のセッションで入力されたコマンドの数を出力しているようです(\!はログアウト/終了後も存続します)。

誰もが「コマンド番号」を便利または意味のある方法で使用する方法を知っていますか?

11
Lagrangian

Bashのコマンド番号は表示専用です

まず、 bashref からの背景:

コマンド番号と履歴番号は通常異なります。コマンドの履歴番号は履歴リスト内の位置であり、履歴ファイルから復元されたコマンドが含まれる場合があります(* bash履歴機能::)。コマンド番号は現在のシェルセッション中に実行された一連のコマンド内の位置。

parse.y でソースを分割すると、'\#'がグローバル静的変数current_command_numberに解決されることがわかります。

case '#':                                                                     
  n = current_command_number;                                                 
  /* If we have already incremented current_command_number (PS4,              
 ${var@P}), compensate */                                                     
  if (orig_string != ps0_Prompt && orig_string != ps1_Prompt && orig_string != ps2_Prompt)
n--;                                                                          
  temp = itos (n);                                                            
  goto add_string;                                                            

eval.c では、コマンドの実行時に増分されます。

# ...
current_command_number++;                                                  

executing = 1;                                                             
stdin_redir = 0;                                                           

execute_command (current_command);                                         

保持されるのは、実際のコマンドや同等の履歴番号ではなく、番号だけです。そのため、各コマンドの実行時に、bashはどのコマンド番号に関連付けられているどのコマンドを忘れて、表示およびスクロール参照以外には何も使用できないようにします。

1
bishop

私の知る限り(そしてこれはあなたの研究で確認されているようです)、そのマジックナンバーをインタラクティブに参照したり、fc!nショートカットを使用したりする方法はありません。これらは確かに、この特定のシェルが起動してからの相対位置ではなく、履歴リスト内の絶対位置のみを参照しているようです(正しく指摘したように\#が参照しています)。

ここでこれをより良くするために私が見つけた唯一の方法は、以下を設定することです:

export HISTFILESIZE=1001
export HISTSIZE=-1

そのように:

  1. 新しいセッションの履歴は1000から始まります。これにより、セッションのどこにいるかを簡単に特定できます
  2. (やや無関係)特定のセッションで古い履歴を失わない(ただし、ファイルをフラッディングしない)

基本的に、それは私の変更されたプロンプト(PS1="\\!$ ")を次のものから変えました:

499$ 

に:

1000$ 

...起動時に少しクリーンになります。しかし、それはおそらくあなたが探していた答えではありません。 :)

(ちなみに、私はzshでも解決策を探しましたが、\#に相当するものがないため、まったく役に立ちません。)

5
anarcat