端末の履歴をhist.txtというファイルに保存するbashスクリプトを作成しようとしています。使用history > hist.txt
はbashスクリプトでは機能しないようですが、コマンドラインで実行すると正常に機能します。
どんなガイダンスも大歓迎です。
ありがとうジュディ
~/.bash_history
ファイルを読み取るだけです。
端末の履歴をhist.txtというファイルに保存するbashスクリプトを作成しようとしています。使用history > hist.txt
はbashスクリプトでは機能しないようですが、コマンドラインで実行すると正常に機能します。
どんなガイダンスも大歓迎です。
ありがとうジュディ
~/.bash_history
ファイルを読み取るだけです。
回答:
source
またはを使用してスクリプトを実行します.
。
source ./script_name.sh
または
. ./script_name.sh
後者は、異なるシェル間でわずかに互換性があります。
この質問は、シェルスクリプトが独自のコンテキストで実行されるという重要なポイントを強調しています。これが何を意味するかを確認するには、次のシェルスクリプトを検討してください。
#!/bin/bash
cd /
ls
これを実行すると、次のような出力が得られます。
bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
しかし、スクリプトを実行した後も、スクリプトを実行する前のディレクトリにいることに気づくでしょう。スクリプトのcd /
内部は、実際にはセッションに影響を与えていません。スクリプトが実行されているコンテキストにのみ影響を及ぼしました。スクリプトを実行するために作成され、スクリプトが戻ると破棄されます。
source
コマンドは、「読み取りと現在のシェルのコンテキストでfilename引数からコマンドを実行する」のような任意のコマンドので、うcd
、その中には現在のセッションに影響します。上記のスクリプトを渡して実行すると、実行source
後にルートディレクトリ内に移動することになります。
この場合の問題は、history
コマンドが現在のシェルコンテキストの履歴を提供することです。スクリプトを使用せずに実行するシェルコンテキストにsource
は履歴がないため、出力ファイルには何も書き込まれません。使用source
すると、正しいコンテキストで実行され、期待どおりに動作します。
NBは:source
シェルは、内蔵されて、いないプログラム自体 -バッシュでは、source
と同義である.
が、一部のシェルでのみが.
動作します-私が使用したsource
、それはより読みやすいですので、この答えで.
はなく、最大の互換性のために、.
するべき利用される。
まず第一に、あなたの履歴はすでにファイルにあることに注意してください。bashを実行している場合、その名前は通常~/.bash_history
です。具体的には、変数HISTFILE
に設定したものです。それを別のファイルにコピーしたい場合は、実行してくださいcat "$HISTFILE" > hist.txt
history
コマンドがbashシェルスクリプトで機能しない理由については、スクリプトが現在のシェルセッションの非インタラクティブな子シェルで実行されるためです。子シェルは、親の環境のすべて(設定された変数のすべてではない)を継承せず、エクスポートされた変数のみを継承します。説明のために、以下のスクリプトは変数の値をエコーします$var
。
#!/bin/bash
echo "$var"
次に、$var
何かに設定してスクリプトを実行します。
$ var="foo"
$ foo.sh
VAR:
次に、最初に変数をエクスポートします。
$ var="foo"
$ export var
$ foo.sh
VAR: foo
ご覧のとおり、変数がエクスポートされると、子シェルで使用できるようになります。
前に述べたように、履歴は変数が指すファイルに保存されます$HISTFILENAME
。これはデフォルトではエクスポートされないため、スクリプトの実行時には設定されません。
$ cat foo.sh
#!/bin/bash
echo "HISTFILE: $HISTFILE"
$ ./foo.sh
HISTFILE:
$ echo $HISTFILE
/home/terdon/.bash_history
上記の例でわかるように、変数HISTFILE
は通常のシェルセッションで設定されていますが、スクリプトの実行時には空です。
したがって、履歴を取得するには、いくつかのオプションがあります。
デフォルトHISTFILE
値は$HOME/.bash_history
です。それを変更していない場合は、スクリプトで次のコマンドを実行するだけです。
cat "$HOME/.bash_history" > history
$HISTFILE
変数をスクリプトに渡すことができますcat
。
#!/bin/bash
cat "$1" > history
上記を保存して、次のようにfoo.sh
実行します。
./foo.sh "$HISTORY"
変数がエクスポートされていることを確認してください。この行を~/.bash_profile
(存在する場合)または~/.profile
(~/.bash_profile
存在しない場合)ファイルに追加します。
export HISTFILE
次に、ログアウトして再度ログインするとhistory > hist.txt
、期待どおりにスクリプトから実行できるはずです。これは、export VAR
「$ VARを子シェルで使用できるようにする」という意味です。実際には、これはHISTFILE
、スクリプトの実行に使用する非対話型シェルによっての値が継承されることを意味します。
これで、HISTFILE
が設定されますが、スクリプトを実行しているシェルによって読み込まれていません。したがって、それを機能させるには、history -r
最初にそれを読む必要があります。スクリプト全体は次のようになります。
$!/bin/bash
history -r
history > hist.txt
または、スクリプトを実行する前に手動でエクスポートします。
$ export HISTFILE
しかし、それでもhistory -r
スクリプトで行う必要があります。
@ p0llardの回答でsource
提案されているようにできます。