ユーザー入力を読み取り、「cal」コマンドを使用して日付を検証する bash スクリプト

ユーザー入力を読み取り、「cal」コマンドを使用して日付を検証する bash スクリプト

入力内容を読み取るスクリプトを作成したいと考えています (たとえば、スクリプトの名前が「check」の場合、「check 9 4 1993」と入力すると、その入力内容が cal コマンドに渡され、カレンダーで日付が有効かどうかが確認されます)。

以下に私が提案するのは、cal コマンドを通した入力がエラーを返した場合は、有効な日付ではないことを意味し、逆にエラーがない場合は、日付が有効であるということです。この草稿には何か大きな問題があることは承知しています (入力が cal コマンドを通されるようにする方法がわかりません) が、何か提案があればありがたいです。とりあえず、草稿を以下に示します。

#!/bin/bash

day=$1; month=$2; year=$3
day=$(echo "$day" | bc)
month=$(echo "$month" | bc)
year=$(echo "$year" | bc)

cal $day $ month $year 2> /dev/null
if [[$? -eq 0 ]]; then
   echo "This is a valid date"
else
   echo "This is an invalid date"
fi

答え1

私が調べた Linux ディストリビューション (Ubuntu 14.04 など) では、パッケージはcalGNU Coreutils ではなく BSD から提供されています。BSD バージョンでは日数がパラメータとして受け入れられないようで、受け入れられるのは月と年だけです。Ubuntu バージョンには -H YYYY-MM-DD オプションがありますが、役に立たないようです。

代わりにユーティリティを使用しますdate。Linux の GNU Coreutils を前提とすると、スクリプトを次のように書き直すことになると思います。

#!/bin/bash

day=$((10#$1))
month=$((10#$2))
year=$((10#$3))

if date -d $year-$month-$day > /dev/null 2>&1; then
    # cal $month $year
    echo "This is a valid date"
else
    echo "This is an invalid date"
fi

ノート:

  • 私はシェルの独自の算術拡張bc各パラメータごとに新しいプロセスを分岐させるのではなく、入力を検証し、先頭のゼロを削除します。
  • 使っていますGNU 日付入力された日付を解析する
  • date コマンドは、if条件式として直接使用できます。 ifは、プロセスの終了コードをチェックすることで機能します。 通常は、または実行可能[ファイル[[が代わりに使用されますが、有用な終了コードで終了する他のプログラムを使用する理由はありません。
  • 実際に正しい日付の出力が必要かどうかはわかりませんcal。必要な場合は、そのcal行のコメントを解除してください。

答え2

[[は実際にはコマンドであり、他のコマンドと同様に引数を区切るために空白が必要です。

if [[ $? -eq 0 ]]; then
# ...^

答え3

$ドルと変数の間にはスペースがありますmonth

cal $day $ month $year 2> /dev/null

そのはず:

cal $day $month $year 2> /dev/null

答え4

「%Y-%m-%d」または「%m/%d/&Y」形式の日付(例:2020-11-29 または 11/29/2020)を入力すると、次のように gnu date (gdate) を使用して日付の有効性を確認できます。

gdate -d "$1" +'%Y-%m-%d' > /dev/null 2>&1  # don't display any output
status=$(echo $?)                           # get error code
if [[ $status = 1 ]]                        # if date is invalid
then
  { echo "This date doesn't exist. Enter valid date!"; exit 1; }
else
  ...

私の質問が正解で、誰かの役に立つことを願っています。私の場合はうまくいきました :)

関連情報