👌

シェル実行時にエラーログのみ別ファイルに吐き出したい

2021/12/20に公開

概要

仕事で以下のような要件で簡単な使い捨てのシェルを書きました。
その際、ログの出力先を振り分けるのに、基本的な知識を使ってシンプルに実現できたのでメモを残します。

  • テスト用に作成されたファイルを削除する
  • 正常に削除できたファイルはファイル名をログに出力する
  • 存在しなかったファイルはファイル名をエラーログに出力する

やりたいこと

サーバーでシェル実行時にエラーだけ別ファイルに吐き出したい。

解決方法

  • ファイルディスクリプタとリダイレクトを組み合わせる

./test.sh > normal.log 2> error.log

2> error.logとすることで、標準エラー出力のみをerror.logに振り分けることができます。
./test.sh > normal.logはファイルディスクリプタが指定されていないですが、
この場合はデフォルトで標準出力になるので./test.sh 1> normal.logと同じ意味になります。

なお、test.shの中身はごく単純なもので、rmコマンドをぶん回しているだけです。
rmコマンドは

test.sh
# ファイル名はランダムな文字列
rm -v /hoge/fuga/xxxx.jpg
rm -v /hoge/fuga/xxxx.jpg
rm -v /hoge/fuga/xxxx.jpg
# 以降続く・・・

実行結果

簡単にサンプルを用意して実行してみました。

削除対象ファイル2つ

$ ls -l
total 0
-rw-r--r--  1 captain-blue  staff  0 Dec 20 22:33 test1.txt
-rw-r--r--  1 captain-blue  staff  0 Dec 20 22:33 test2.txt

削除シェル

#!/bin/bash

rm -v test1.txt
rm -v test2.txt
rm -v test3.txt

実行してみます。

$ ./remove.sh > normal.log 2> error.log

$ ls -l
total 24
-rw-r--r--  1 captain-blue  staff  41 Dec 20 22:41 error.log
-rw-r--r--  1 captain-blue  staff  20 Dec 20 22:41 normal.log
-rwxr-xr-x@ 1 captain-blue  staff  61 Dec 20 22:39 remove.sh

$ cat normal.log
test1.txt
test2.txt
$ cat error.log
rm: test3.txt: No such file or directory

無事エラーログを分けて出力できました。

最後に

ファイルディスクリプタとか、めっちゃ基本ですがそれを実務でサクッと応用できると身についたなーと感じますね。

参考

https://qiita.com/laikuaut/items/e1cc312ffc7ec2c872fc

https://e-words.jp/w/ファイルディスクリプタ.html

Discussion