ARGV []はパラメータを受け入れません。

ARGV []はパラメータを受け入れません。

パラメータを渡そうとするシェルスクリプトがあり、スクリプトに空の出力が表示されますdateARGV[1]

これはコマンドです:

#!/bin/bash
dt=$(date -d "yesterday" '+%m%d%Y')
cat /tmp/log.$AUTOSERVE.$dt \
  | perl -ne '/STATUS:\s+(\w+).+MACHINE:\s+(\w+.\w+.\w+)$/ && print join( "\t", $1, $2 ). "\n"' \
  | grep -E '(SUCCESS|FAILURE|TERMINATED)' \
  | cut -f2 \
  | sort \
  | uniq -c \
  | perl -ne '/^\s+(\d+)\s+(.*)$/ && print join("\t", '$ARGV[1]', $ENV{AUTOSERV}, $2, $1) . "\n"' $date_YYYYMMDD \
  > /tmp/output.txt

私は何が間違っていましたか?

ここで私がやりたいことを説明します。

毎日次の名前でログファイルを生成します。

log.$AUTOSERVE.mmddyyyy

ログファイルには次のデータが含まれます。

理解を深めるために、入力日を変更しました。

Time            Message           
____________________________________________

[11/16/2023 07:13:45]    CAUAJM_I_12345 The application has rollover

[11/16/2023 07:13:45]     CAUAJM_I_11111  The machine 111.test.com has lost connection
[11/16/2023 07:13:45]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: FAILURE         JOB: ABC MACHINE: 111.test.com EXITCODE: 1

[11/16/2023 07:13:45]      CAUAJM_I_40245 [222.test.com connected to ABC]

[11/16/2023 07:13:45] CAUAJM_I_40245 EVENT: CHANGE_STATUS    ALARM: JOBFAILURE         JOB: ABC EXITCODE: 1
[11/16/2023 07:13:45]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: TERMINATED      JOB: XYZ MACHINE: 222.test.com
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: STARTING        JOB: 123 MACHINE: 333.test.com
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: SUCCESS         JOB: 456 MACHINE: 444.test.com EXITCODE: 0
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: SUCCESS         JOB: ABC123 MACHINE: 555.test.com
[11/16/2023 07:13:45]      CAUAJM_I_40245 [222.test.com connected to ABC]
[11/16/2023 07:13:45]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: FAILURE         JOB: ABC MACHINE: 111.test.com EXITCODE: 1
[11/16/2023 07:13:45]      CAUAJM_I_40245 [333.test.com connected to 123]
[11/16/2023 07:13:45]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: TERMINATED      JOB: XYZ MACHINE: 222.test.com
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: STARTING        JOB: 123 MACHINE: 333.test.com
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: SUCCESS         JOB: 456 MACHINE: 444.test.com 
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: SUCCESS         JOB: ABC123 MACHINE: 555.test.com EXITCODE: 0

このシェルスクリプトは、logこのファイルのMACHINEおよびSTATUS検索文字列をフィルタリングし、各システムで実行されているジョブの数を計算します。

私が得た結果は次のとおりです。

            NP2     111.test.com      2
            NP2     222.test.com      2
            NP2     444.test.com      2
            NP2     555.test.com      2

$date_YYYYMMDDに変えようとしました。$dt:

cat /tmp/log.$AUTOSERVE.dt \
  | perl -ne '/STATUS:\s+(\w+).+MACHINE:\s+(\w+.\w+.\w+)$/ && print join( "\t", $1, $2 ). "\n"' \
  | grep -E '(SUCCESS|FAILURE|TERMINATED)' \
  | cut -f2 \
  | sort \
  | uniq -c \
  | perl -ne '/^\s+(\d+)\s+(.*)$/ && print join("\t", $ARGV[1], $ENV{AUTOSERV}, $2, $1) . "\n"' $dt \
  > /tmp/output.txt

ただし、次のエラーが発生します。

Can't open 11152023: No such file or directory.

$AUTOSERVEこの出力に値を提供する環境変数があると仮定すると、NP2予想される結果は次のとおりです。

11152023   NP2     111.test.com      2
11152023   NP2     222.test.com      2
11152023   NP2     444.test.com      2
11152023   NP2     555.test.com     2

ベストアンサー1

似たようなものが欲しいようです。

#! /bin/sh -
DT=$(date -d yesterday +%m%d%Y) || exit
export DT
exec perl -lne '
  if (
    ($status, $machine) = /STATUS:\s+(\w+).+MACHINE:\s+(\w+\.\w+\.\w+)$/ and
    $status =~ /^(SUCCESS|FAILURE|TERMINATED)\z/
  ) {$count{$machine}++}
  END {
    for (keys %count) {
      print join "\t", $ENV{DT}, $ENV{AUTOSERVE}, $_, $count{$_};
    }
  }' < ~/tmp/log."$AUTOSERVE.$dt" > ~/tmp/output.txt

メモ:

  • たとえば、固定名のファイルは誰でも書き込み可能なディレクトリで使用しないでください。/tmpしたがって、ここに切り替えるか、または//...の専用領域を使用してください~/tmp/var~/var~/.local$XDG_RUNTIME_DIR

  • このコードにはbashに関連する内容がないため、bashの依存関係を追加する必要はありません。

  • 追加の-nパラメータはperlスクリプトへの入力です。

  • Chrisがすでに述べたように、あなたの引用に問題があります。

  • あなたはAUTOSERV/AUTOSERVE違いがあります。

  • .単一文字に一致する正規表現演算子です。テキストポイントを一致させるには、\.またはを使用します。[.]

  • 使用法はdateGNUによって異なります。すべてのdate実装が-dオプションをサポートしているわけではなく、サポートしている場合は、BSDの項目や認識できない項目(ビジボックスやおもちゃ箱 yesterdayなど)など、まったく関連のない項目に使用できます。このスクリプトをGNU以外のシステムに移植する必要がある場合は、日付操作も可能です。dateperl

  • 次のように、単一の正規表現を使用するように簡単に変更できます。

    /STATUS:\s+(?:SUCCESS|FAILURE|TERMINATED)\b.+MACHINE:\s+(\w+.\w+.\w+)$/
    
  • マシンのリストをアルファベット順に並べ替えるには、をkeys %countに置き換えます。sort cmp, keys %count

  • execこのようなラッパースクリプトで非常に一般的なのは、プロセスを保存することです。perl子プロセスで実行し、待つのではなく、同じプロセスで実行するようにシェルに指示します。cmd+ fork()&をexec(cmd)実行しますがwait(child)exec cmdおそらくと呼ばれる必要がありますnofork cmdexec(cmd)、入力に時間がかかりますが、システムの実行はより簡単で短く、リソースの使用量が少なくなります。

  • %m%d%Yタイムスタンプ形式を選択することはお勧めできません。あいまいで、語彙順(の出力と同様ls)が年代順と一致しません。%Y-%m-%dそれとも%F普遍的に認識され、語彙的に年代順(少なくとも0001から9999まで)にソートされるので、より良いです。

  • catファイルをリンクするコマンドです。ファイルに使用することは意味がありません。cmd < input > output(または、<input cmd >outputしかしいいえ cmd > output < inputinput)には、読み取り用に開くことができない場合はcmd実行されず、output削除されないという追加の利点があります。


1たとえば、ここに-MPOSIXaBEGIN{@t = localtime; $t[3]--; $dt = strftime "%m%d%Y", @t}またはハッキングとして追加します-M'POSIX;@t = localtime; $t[3]--; $dt = strftime "%m%d%Y", @t'

おすすめ記事