
dateコマンドで生成されたエラーを抑制しようとしましたが、スクリプトを実行した後もエラーが発生します。
#!/usr/bin/bash
input="30 FEB 2022"
reg="^[0-9]{1,2}\s[a-zA-Z]{1,3}\s[0-9]{1,4}$"
if [[ $input =~ $reg ]]
then
echo "VALID Date Format : $input"
#output=$(`date -d "$input" +"%d-%b-%Y, %A"` 2>&1 > /dev/null)
output=`date -d "$input" +"%d-%b-%Y, %A"` 2>&1 > /dev/null
else
echo "INVALID Date Format : $input"
output="-1"
fi
echo $output
実行後の出力 -
root@ip-xx-x-xx-xxx:~# ./exDate.sh
VALID Date Format : 30 FEB 2022
date: invalid date '30 FEB 2022'
エラーを抑制する方法を教えてください。
答え1
より良い方法を提供する回答がすでにあるので、あなたが要求した質問にのみ答えます。エラーメッセージが引き続き表示されるのは、リダイレクトの順序が重要なためです。リダイレクトは左から右に読み込まれるため、2>&1 > /dev/null
「最初にstderrをstdoutにリダイレクトしてから」を意味します。それからstdoutを/dev/null
「にリダイレクトします。これはエラーがstdoutとして印刷され、通常のstdoutがにリダイレクトされることを意味します。stdout/dev/null
を次にパイプすることでこれを確認できますwc
。
## No redirection
$ date -d foo
date: invalid date ‘foo’
## Nothing is printed to stdout, the error goes to stderr
## and wc has nothing to count
$ date -d foo | wc
date: invalid date ‘foo’
0 0 0
## Redirect using 2>&1 > /dev/null
$ date -d foo 2>&1 > /dev/null
date: invalid date ‘foo’
## The error is now being printed to stdout, wc counts it
$ date -d foo 2>&1 > /dev/null | wc
1 4 29
あなたが望むのは、標準出力を/dev/null
最初の出力にリダイレクトし、それからstderrをstdoutにリダイレクトします> /dev/null 2>&1
。期待どおりに動作します。
$ date -d foo > /dev/null 2>&1
$
答え2
正規表現やパターンを使用して日付を確認することはできません。 (まあ、おそらくそうすることができるようですが、それは不快です。)
代わりに、date
コマンド自体を使用して入力を検証します。このスクリプトをファイルに作成exDate
して実行可能にします(chmod a+x exDate
)。
#!/bin/bash
input=$1
if date --date "$input" >/dev/null 2>&1
then
# Good date
output=$(date --date "$input" +'%d-%b-%Y, %A')
else
# Date parsing failed
printf 'INVALID Date Format : %s\n' "$input" >&2
output='-1'
fi
printf "%s\n" "$output"
実行例
./exDate '30 FEB 2022'
INVALID Date Format : 30 FEB 2022
-1
./exDate '24 FEB 2022'
24-Feb-2022, Thursday
./exDate '2022-04-13'
13-Apr-2022, Wednesday
最後のオプションが許可されていない場合(つまり、フォームの日付のみを許可したい場合d(d) MMM yyyy
)、次のようにパターンマッチングとdate
検証が必要です。
if [[ "$input" =~ ^[0-9]{1,2}\ [a-zA-Z]{3}\ [0-9]{4}$ ]] && date…
then
if date...
割り当てとマージしてコードを単純化output=
し、失敗したケースを処理するだけです。
if ! output=$(date --date "$input" +'%d-%b-%Y, %A' 2>/dev/null)
then
# Date parsing failed
printf 'INVALID Date Format : %s\n' "$input" >&2
output='-1'
fi
答え3
デフォルトの入力日付形式は米国です。月は日付の前になければなりません。
$ date -d '02/02/2022'
Wed 02 Feb 2022 12:00:00 AM UTC
$ date -d '02/22/2022'
Wed 22 Feb 2022 12:00:00 AM UTC
はい、月は文字で表示できます(ロケールが他の国にある場合でもFEBまたは2月)。
$ date -d 'FEB 22 2022'
Tue 22 feb 2022 00:00:00 UTC
$ ( LC_ALL=es_ES.utf8 date -d 'FEB 22 2022')
mar 22 feb 2022 00:00:00 UTC
$ ( LC_ALL=ja_JP.utf8 date -d 'FEB 22 2022')
2022年 2月 22日 火曜日 00:00:00 UTC
ただし、どんな日付でも可能ではありません。いいえ日付が与えられたら、エラーを報告してみてください。存在しない。 2月30日は存在しません。この場合、日付は出力されません。そして終了状態を1に設定します。実際には、正規表現がなくても入力日を検証できます。
#!/bin/bash
input="${1:-"30 FEB 2022"}"
if output=`date -d "$input" +"%d-%b-%Y, %A" 2>&1`
then echo "VALID Date : $input"
else echo "INVALID Date : $input"
output="-1"
fi
printf '%s\n' "$output"
もちろん、リダイレクトは次の場所になければなりません。`...`
彼らが働くようにしてください。
$ ./exDate.sh
INVALID Date : 30 FEB 2022
-1
$ ./exDate.sh "22 FEB 2022"
INVALID Date : 22 FEB 2022
-1
$ ./exDate.sh "FEB 22 2022"
VALID Date : FEB 22 2022
22-Feb-2022, Tuesday
$ ./exDate.sh "FEB 30 2022"
INVALID Date : FEB 30 2022