
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 5
echo 4
echo 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
れているためです。これは、他のユーザーと共有サーバー上で作業していて、たとえばパスワードやその他の機密情報が含まれているために、特定のコマンドを履歴に保存して他の人に見られないようにしたい場合に特に便利です。ignorespace
ignoreboth
ignorespace
ignoredups
ただし、コマンドの前に空白がない場合でも、次のようになります。
$ var=5
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
通常は または前述の が含まれるecho $((var--))
ため、 ~/.bash_history には1 つのエントリのみが含まれる可能性が高くなります。このすべては、システムで で呼び出すことができる Bash マニュアルページの セクションで説明されています。HISTCONTROL
ignoredups
ignoreboth
HISTCONTROL
man bash