bashスクリプト内の履歴コマンド


20

履歴はシェル組み込みコマンドであり、BASHスクリプト内で使用できませんでした。だから、BASHスクリプトを使用してこれを達成する方法はありますか?
ここで、私のスクリプトを紹介します。

#!/bin/bash
history |  tail -100 > /tmp/history.log
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

回答:


31

Bashはデフォルトで非対話型シェルの履歴を無効にしますが、有効にすることができます。

#!/bin/bash
HISTFILE=~/.bash_history
set -o history
history | tail 

ただし、そのサーバー上のアクティビティを監視しようとしている場合、シェルの履歴は役に立ちません(履歴に表示されないコマンドを実行するのは簡単です)。Linuxでのすべてのプロセス起動をログに記録するにはを参照してください。

スクリプトをデバッグしている場合、シェル履歴は有用な情報を取得する最良の方法ではありません。はるかに優れたツールは、デバッグトレース機能ですset -x。スクリプトの先頭近くに配置します。トレースは標準エラーに書き込まれます。


これは、スクリプト内で作業することを拒否:histtest.sh: 5: set: Illegal option -o history
ケン・シャープ

4
@KenSharpこれは、shスクリプトで使用しようとしたためです(そしてsh、エラーメッセージの正確な文言でダッシュジャッディングしています)。bashの履歴にアクセスするには、bash(#!/bin/bashまたはで始まるスクリプト#!/usr/bin/env bash)を使用する必要があります。
ジル 'SO-悪である停止

1
@KenSharpはい、そうです。エラーメッセージが表示されたら、ダッシュの下で実行したことは明らかです。BashにはエラーメッセージがありませんIllegal option(言うでしょうset: history: invalid option name)。
ジル 'SO-悪であるのをやめる'

これに伴う問題は、それが以下のすべてのコマンドが追加されていることであるset -o history 、その後のようなエントリで詰まっれようとしている歴史にif [... vars=$(...など
ナス

1
@nathそれは質問が求めたものです。私が指摘するように、それはほとんど無意味です。アクティビティの監視は、シェルの履歴では解決できない難しい問題です。スクリプトをデバッグする場合set -xは、はるかに便利です。
ジル「SO-悪であるのをやめる」

6

非対話型で実行するときに実際に履歴機能を使用するかどうかはわかりません。そうしないと、実行するすべてのシェルスクリプトがコマンド履歴を乱雑にします。

ソースに直接行かないのはなぜ${HOME}/.bash_history、交換してくださいhistory | tail -100tail -100 ${HOME}/.bash_history。(タイムスタンプを使用する場合、おそらくの行に沿って何かをする必要がありますgrep -v ^# ${HOME}/.bash_history | tail -100)。


確かに、タイムスタンプを使用して、実際にgreq -v '^#[0-9]\+$'(シェルでコメントを「実行」することがあります...)
PlasmaBinturong

実際、私の場合、正しい履歴行番号を使用する必要がありhistoryますが、grepメソッドの出力とメソッドの出力には違いがあります...
PlasmaBinturong

わかりました、修正はこのように履歴リストを履歴ファイルと同期することでした:history -a; history -c; history -r。(追加、クリア、読み取り)
PlasmaBinturong

2

historyスクリプトでアクティブなシェルセッションからのコマンドの出力を使用する場合は、エイリアスを使用して最初にコマンドを実行できます。次に、同じエイリアスで、スクリプトの残りを呼び出すことができます。このような構成を使用するhistoryと、実際のスクリプトにコマンドがある場合と本質的に同じ結果を達成できます。

たとえば、スクリプトの名前がscript.shであると仮定して、次のようなエイリアスを作成できます。

alias hy_tmp='history | tail -100 > /tmp/history.log ; bash /patch/to/script.sh'

スクリプトを次のように変更します。

#!/bin/bash
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

~/bash_history2台のコンピューターでファイルを結合、並べ替え、同期するプロセスを書いているときにこの質問を見つけたので、過去に使用したコマンドを簡単に検索できます。

更新するために新しいシェルにログインしなくても、累積履歴ファイルを更新するのは面倒ではありません~/bash_history。サーバーを監視する場合、他の回答で述べたように、これは明らかに機能しません。

特に私の使用法は次のとおりです。

alias hbye='history | cut -c 8- > /home/chris/.bash_history_c; bash /hby.sh

スクリプトhby.shは、すべての~/.bash_history*ファイルからすべての一意のエントリをプルします。



1

script.sh次の名前のスクリプトを作成します。Xという名前のスクリプトを作成し、その中にY行の履歴の行を入れます。

#!/bin/bash
SCRIPT_NAME=$1
NUMBER_OF_LINES_BACK=$2

# Enable History in a non interactive shell
HISTFILE=~/.bash_history
set -o history

# echo shabang line and x number of lines of history to new script
echo \#\!\/bin\/bash > $SCRIPT_NAME.sh; history | tail -n $NUMBER_OF_LINES_BACK >> $SCRIPT_NAME.sh;
chmod u+x $SCRIPT_NAME.sh;

# Open the newly created script with vim
vim $SCRIPT_NAME.sh;
~

次に、最後の14行の実行中に作業していた「task」という名前のタスクを実行するスクリプトを作成する場合

script.sh task 14

次に、履歴をクリーンアップして、すばらしいスクリプトを作成します。


histtest.sh: 5: set: Illegal option -o history
ケンシャープ

1

bashスクリプトでは、historyコマンドはデフォルトで無効になっているため、.shファイルではhistoryコマンドも機能しません。リダイレクトのために、bsh_historyファイルを.shファイル内にリダイレクトしてください。

または履歴メカニズムを有効にするには、履歴ファイルに言及し、以下で説明するようにランタイムパラメータを変更します。

#!/bin/bash
HISTFILE=~/.bash_history
set -o history 

注:上記のスクリプトファイルの上部の2行。履歴コマンドが履歴で機能するようになりました。


0

すべてのユーザーは、履歴コマンドの結果である独自の履歴ファイルを持っています。シェルスクリプトで履歴コマンドを使用する代わりに、ユーザー用の履歴ファイルを使用できます。あります.bash_historyユーザーのための履歴ファイルになり、ユーザのホームディレクトリ内のファイル、。


-1

短い答え

history -p明示的に履歴展開を実行するために使用します。

次に例を示します。

私にとってよくあるユースケースは次のとおりです。

  • 前のコマンドはファイル名のリストを取得し、stdoutに出力します。
  • これらのファイルをvimで編集する必要があります。

私のbashがされているのでset -o histexpand、通常私がやったことはタイピングです

vim $(!!)

前のコマンドでリストされたファイルを編集します。

悲しいことに間違いが起こることがあるので、による検証を有効にしshopt -s histverifyます。

これで、Returnキーを1つ追加するだけで、拡張を検証できます。

今日は、これらの詳細を頻繁に使用するため、これらの詳細をbash関数にラップします。

function vk() {
    set -o history && set -o histexpand;
    vim -i ~/.viminfok $($(history -p !!));
}

ここでは、2つのネストされたを使用します。command substitution内側のもの!!は前のコマンドに展開し、外側のものはそれを実行して出力を取得します。

これで、3つのキーだけで同じ効果を得ることができ、そのうちの1つがReturn

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.