Bash for ループ - ループ内のコマンドをシェルの履歴に追加できますか?

Bash for ループ - ループ内のコマンドをシェルの履歴に追加できますか?

bash ターミナルで次の for ループを実行すると、

 for i in {1..5}; do echo $i;  done

コマンドechoは現在のシェルの履歴に追加されません。これは、for (in section) 内のコマンドがサブシェルで実行されるためでしょうか。もしそうなら、代わりに現在のシェルで実行する方法はありますか。それとも、その時点でdo「実行中」なので不可能なのでしょうか。for

編集: for ループ全体を 1 つの複合コマンドとして扱う場合、for ループを削除して個々のコマンドを 5 行に記述すると、5 つすべてが履歴に追加されるのではないですか?

私は次のことを行いました:

#!/bin/bash

set -o history

    var=5
    echo $((var--)) 
    echo $((var--)) 
    echo $((var--)) 
    echo $((var--)) 
    echo $((var--)) 

そして、 を使用してスクリプトを実行しましたsource。 履歴にはまだ 5 つすべてではなく、 1 つの echo ステートメントのみが表示されますecho $((var--)) 。 一方、 5 つではなく5 つの、、 ...コマンドecho $((var--)) を入力すると、 5 つすべてが履歴に追加されます。echo 5echo 4echo 1

なぜ?

答え1

$HISTFILEスクリプトは、実行前にエクスポートしない限り、そもそも ~/.bash_history に履歴を保存しません。そのman bash理由は次の通りです:

HISTFILE が設定されていない場合、または履歴ファイルが書き込み不可の場合、履歴は保存されません。

HISTFILEは環境変数ではなくシェル変数なので、子プロセスであるスクリプトでは使用できません。また、これらのコマンドを実行しても

$    var=5
$    echo $((var--))
$    echo $((var--))
$    echo $((var--))
$    echo $((var--))
$    echo $((var--))

(プロンプトの後の空白に注意) 対話型セッションでスクリプトでない場合は、実際には ~/.bash_history に保存されません。Ubuntu などの一般的な Linux ディストリビューションでは、 1 つ以上の空白で始まるコマンドを保存しないようにまたは(およびのエイリアス ) が設定さHISTCONTROLれているためです。これは、他のユーザーと共有サーバー上で作業していて、たとえばパスワードやその他の機密情報が含まれているために、特定のコマンドを履歴に保存して他の人に見られないようにしたい場合に特に便利です。ignorespaceignorebothignorespaceignoredups

ただし、コマンドの前に空白がない場合でも、次のようになります。

$ var=5
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))

通常は または前述の が含まれるecho $((var--)) ため、 ~/.bash_history には1 つのエントリのみが含まれる可能性が高くなります。このすべては、システムで で呼び出すことができる Bash マニュアルページの セクションで説明されています。HISTCONTROLignoredupsignorebothHISTCONTROLman bash

関連情報