質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

grep

grepはコマンドライン上でテキスト検索を可能にするユーティリティーです。元はUnixのために用意されたものです。

if

if文とは様々なプログラミング言語で使用される制御構文の一種であり、条件によって処理の流れを制御します。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

Q&A

解決済

4回答

1326閲覧

[bash] set -e を付けた時のファイルの空チェックの挙動

maok

総合スコア5

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

grep

grepはコマンドライン上でテキスト検索を可能にするユーティリティーです。元はUnixのために用意されたものです。

if

if文とは様々なプログラミング言語で使用される制御構文の一種であり、条件によって処理の流れを制御します。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

0グッド

0クリップ

投稿2020/07/16 07:30

質問事項

指定のディレクトリ (target_dir) にあるlogファイルから "Error" という文字列が含まれる行を抽出してきたファイル (error.log) を作り、このファイルが空なら "OK"、空でないなら "NG" というスクリプトを作っています。bashでset -eを付けていると、if文の部分がうまく動きません。ファイルが空でない場合はきちんと動くのですが、ファイルが空の場合の処理が実行されないのです (実行すると何も表示されずに終わる)。何がおかしいのかわからず質問いたしました。よろしくお願いいたします。

該当のソースコード

bash

1#!/usr/bin/env bash 2 3set -e 4 5grep Error ./target_dir/*.log > error.log 6 7if [ -s error.log ]; then 8 echo "NG" 9else 10 echo "OK" 11fi

試したこと

grepでerror.logを作らず、単にerror.logを用意するとうまくいきます。

bashのバージョン

bash

1$ bash --version 2GNU bash, バージョン 4.2.46(2)-release (x86_64-redhat-linux-gnu) 3Copyright (C) 2011 Free Software Foundation, Inc.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

bashでset -eを付けていると、if文の部分がうまく動きません。

はい、grepの終了コードは、見つからなかった場合に1となりますので(man)、set -eの効果でシェルスクリプトが終了してしまいます。

grep Error ./target_dir/*.log > error.log || :のように、失敗しても行全体では0を返すようにしておきましょう。

投稿2020/07/16 07:37

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maok

2020/07/16 07:56

明快な回答ありがとうございます。
guest

0

期待している動作にならないのは set -e を指定しているにも関わらず grep がエラーで終了しているからです。今は error.log にファイル出力していますが、本当は必要なくて単に「Error のありなしだけ判定したい」で構わないのであれば以下でも OK です。

bash

1#!/usr/bin/env bash 2 3if grep -q Error ./target_dir/*.log; then 4 echo "NG" 5else 6 echo "OK" 7fi

投稿2020/07/16 07:48

編集2020/07/16 08:02
mattn

総合スコア5030

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ええと、set -eを付けると、サブシェルで実行したコマンドがエラーを返してきた時点でこのシェルが終了します。
そして、grepは検索パターン(今回はError)にマッチする行が見つからないとエラー(-1)を返します。

なので、その後のifの処理を行なう前にこのスクリプトを実行しているシェルが終了してしまうので、ifの処理は行われないことになります。

grepを使わずにerror.logを用意していれば、エラーを返すコマンドがないので、ifの処理が行われます。

要するに、あなたの書いた通りに動いています
set -eを付ける必要はありませんよね。

投稿2020/07/16 07:45

Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

set -eの意味をわかっていますでしょうか?
コマンドが戻り値0以外で終了したら、そこでスクリプトの実行を中断します。

対応としては、set -eをやめます(おすすめ)。

あるいは、

Bash

1#!/usr/bin/env bash 2set -e 3 4if grep Error ./target_dir/*.log > error.log 5then 6 echo "NG" 7else 8 echo "OK" 9fi

とか、あるいは、バッドノウハウな気はしますが、

Bash

1#!/usr/bin/env bash 2set -e 3 4grep Error ./target_dir/*.log > error.log && true 5 6if [ -s error.log ] 7then 8 echo "NG" 9else 10 echo "OK" 11fi

ところで、#!/usr/bin/env bashは初めて見ましたが、/bin/bashが無い環境でしょうか?どんな環境でしょう?

投稿2020/07/16 07:45

otn

総合スコア84538

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問