[解決済み] Bashで最後に実行したコマンドをエコーする?
質問
bashスクリプトの中で最後に実行されたコマンドをechoしようとしています。私はそれを行うための方法を見つけたいくつかの
history,tail,head,sed
これは、パーサーの立場から見て、コマンドがスクリプトの特定の行を表している場合にはうまくいきます。しかし、ある状況下では期待された出力が得られません。例えば、コマンドが
case
文の中に挿入された場合などです。
スクリプトが
#!/bin/bash
set -o history
date
last=$(echo `history |tail -n2 |head -n1` | sed 's/[0-9]* //')
echo "last command is [$last]"
case "1" in
"1")
date
last=$(echo `history |tail -n2 |head -n1` | sed 's/[0-9]* //')
echo "last command is [$last]"
;;
esac
出力されます。
Tue May 24 12:36:04 CEST 2011
last command is [date]
Tue May 24 12:36:04 CEST 2011
last command is [echo "last command is [$last]"]
[Q] bash スクリプトのどこでどのようにコマンドが呼び出されたかに関係なく、最後に実行されたコマンドをエコーする方法を見つけるのを誰か助けてくれませんか?
私の答え
SO'erの仲間からのありがたい貢献にもかかわらず、私は
run
関数 (すべてのパラメーターを 1 つのコマンドとして実行し、失敗したときにコマンドとそのエラー コードを表示する) を書くことを選択しました。
-チェックしたいコマンドの前に
run
これはそれらを1行にまとめ、スクリプトの簡潔さには影響しません。
-これらのコマンドのいずれかでスクリプトが失敗するたびに、私のスクリプトの最後の出力行は、どのコマンドが失敗したかをその終了コードとともに明確に表示するメッセージになり、デバッグが容易になります。
スクリプトの例です。
#!/bin/bash
die() { echo >&2 -e "\nERROR: $@\n"; exit 1; }
run() { "$@"; code=$?; [ $code -ne 0 ] && die "command [$*] failed with error code $code"; }
case "1" in
"1")
run ls /opt
run ls /wrong-dir
;;
esac
出力されます。
$ ./test.sh
apacheds google iptables
ls: cannot access /wrong-dir: No such file or directory
ERROR: command [ls /wrong-dir] failed with error code 2
複数の引数、引数としてのbash変数、引用された引数...を持つ様々なコマンドをテストしてみました。
run
関数はそれらを壊しませんでした。私がこれまでに見つけた唯一の問題は、壊れるエコーを実行することですが、私はとにかく私のエコーをチェックするつもりはありません。
どのように解決するのですか?
コマンド履歴は、対話型の機能です。履歴に入力されるのは、完全なコマンドのみです。例えば
case
という構文は、シェルが解析し終わった時点で全体として入力されます。履歴を検索する際に
history
による履歴の検索も、シェル展開 (
!:p
)) は、あなたが望んでいると思われること、つまり単純なコマンドの呼び出しを表示することを行います。
は
DEBUG
トラップ
を使うと、単純なコマンドの実行の直前にコマンドを実行することができます。実行するコマンドの文字列版(単語はスペースで区切られています)は
BASH_COMMAND
変数に格納されます。
trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
…
echo "last command is $previous_command"
なお
previous_command
はコマンドを実行するたびに変化するので、それを利用するために変数に保存しておく。前のコマンドの戻り値も知りたい場合は、両方を1つのコマンドに保存してください。
cmd=$previous_command ret=$?
if [ $ret -ne 0 ]; then echo "$cmd failed with error code $ret"; fi
さらに、コマンドに失敗したときだけ中断したい場合は
set -e
を使って、最初の失敗したコマンドでスクリプトを終了させることができます。最後のコマンドを表示するには
EXIT
トラップ
.
set -e
trap 'echo "exit $? due to $previous_command"' EXIT
もし、スクリプトが何をしているのか追跡しようとするならば、 このようなことは忘れて、次のように使ってください。
set -x
.
関連
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] プログラムの実行やシステムコマンドの呼び出しはどのように行うのですか?
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで通常のファイルが存在しないかどうかを判断する方法を教えてください。
-
[解決済み] Bashで文字列変数を連結する方法
-
[解決済み] Bash prints リテラルの改行をエコーする \n
-
[解決済み] Bashスクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashでコマンドライン引数を解析するには?
-
[解決済み] Bashでコマンドの出力に変数を設定するにはどうすればよいですか?
-
[解決済み] シェルコマンドを実行しながらエコーする方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 特定のコマンドを無視するBashのエラー
-
[解決済み] find を使ってサブディレクトリを除外する
-
[解決済み] Makefileでシェルコマンドを使用する方法
-
[解決済み] シェルスクリプトによるDockerコンテナ内でのスクリプトの実行
-
[解決済み] ENV 変数やデフォルト値を使って Makefile の変数を定義する
-
[解決済み] Bashでコマンドライン引数を変更するには?
-
[解決済み] bashでファイルが存在するかどうかをテストするためのWhileループ
-
[解決済み] bashのifブロックの中でboolean変数を評価する方法は?重複
-
[解決済み] zip アーカイブの中の1つのファイルを更新する方法
-
[解決済み] ファイル名の一部をリネームする [重複]。