シェルスクリプトのelseの近くに構文エラーがあります。

シェルスクリプトのelseの近くに構文エラーがあります。

以下のコードを試しています。確認しようとしているので、以下のディレクトリに2つのファイルがあり、whileループを完全に削除したいと思います!しかし、まだファイルを受け取っていない場合は、繰り返し続けて待つ必要があります。しかし、以下のコードを使用すると、他の部分でエラーが発生します。エラーは次のとおりです。

syntax error near unexpected token else

問題を解決するにはどうすればよいですか?もう1つの質問は、Visual Studio Codeでシェルスクリプトをフォーマットする方法です。 VSC では、この拡張機能が見つかりません。

day_of_month=1
export filesdir=/dir1/dir2/dir3
local count=0
numFilesReceived=0
while true; do
        files=$(find $filesdir -name '*.txt.gz' -type f -mmin -1)
        if [ "$day_of_month" == "1" ]; then
            if [ -f "$files" ]; then
                count=$((count + 1))
                break
                if [ "$numFilesReceived" == "$count" ]; then
                    echo "All $count data received!"
                    break 3
                fi
            fi
            else
                echo "No data received yet!" 
            fi
            fi
             else
            rm $files
        fi
       done

答え1

if/else のバランスが悪いため、エラーが発生します。 shスクリプトのif / else構文は次のとおりです。

if condition 
then
    do something
else
    do something else
fi

それぞれはif1つで閉じる必要がありますfi。次に、すべてのファイルを単一の文字列変数に保存します。

files=$(find $filesdir -name '*.txt.gz' -type f -mmin -1)

これはfind、コマンドが次のようなものを返す場合を意味します。

$ find . -name '*.txt.gz' -type f
./file2.txt.gz
./file1.txt.gz

その後、変数の内容は次のようになります。

$ files=$(find . -name '*.txt.gz' -type f)
$ echo "$files"
./file2.txt.gz
./file1.txt.gz

ただし、その名前のファイルが存在することを確認してください。

if [ -f "$files" ]; then

リテラル名を持つファイルがないため、これは決して真実ではなく、./file2.txt.gz\n./file1.txt.gzそのようにしても結果に含まれます。それにもかかわらず、あなたはそれがファイルであり、存在することをすでに知っています。findコマンドが実行する操作なので、このテストはさらに不要になります。

また、常に真であるため、設定してday_of_month=1使用する必要がない不要な変数がたくさんあります。そしてif [ "$day_of_month" == "1" ]江戸同様です。この2つは何をしたいのか分からないので、ゼロ以外の値に設定してから、ファイル数がその値と一致する場合は終了したいようです。これも要点がわかりません。毎月1日ならファイルを削除したいようです。もしそうなら、現在の日付も確認したいと思います。numFilesReceivedcountcountday_of_month

あなたが望むものについての最良の推測の実際のバージョンは次のとおりです。

#!/bin/bash

filesdir=/dir1/dir2/dir3
expectedFiles=2
dayToDelete=1

## Get the current day of the month
day_of_month=$(date '+%d')

while true; do
  ## If this is not the 1st day of the month, just delete the files
  ## and exit
  if [ "$day_of_month" != "1" ]; then
    find "$filesdir" -name '*.txt.gz' -type f -mmin -1 -delete
    exit
  ## If this is the first day of the month
  else
    ## You don't need the file names, only their number,
    ## so just print a dot so you don't need to worry about
    ## whitespace in the names
    fileCount=$(find "$filesdir" -name '*.txt.gz' -type f -mmin -1 -printf '.\n' | wc -l)
    if [[ "$fileCount" == "$expectedFiles" ]]; then
      echo "All $expectedFiles files received!"
      exit 
    else
      echo "No data received yet!"
      ## Wait for 5 seconds. No point in spamming, in fact you
      ## probably want to sleep for longer.
      sleep 5
    fi
  fi
done

これが実際に必要なものではないようですが、これが出発点になることを願っています。さらに助けが必要な場合は、新しい質問をしてください。ただし、より良いサポートを提供するためにスクリプトが実行する必要がある作業の詳細を提供してください。

答え2

3つの「if」ドアと5つの「fi」ドアがあります。

それは他のものではありません。ちょうど違うものです。

関連情報