shell 脚本中 else 附近的语法错误

Avi*_*tor 0 shell bash

我正在尝试下面的代码。因为我试图检查我在下面提到的目录中获得了两个文件,然后我想完全摆脱 while 循环!但是如果我还没有收到文件,那么它应该继续迭代和等待。但是通过使用下面的代码,我在 else 部分遇到了错误。错误是:

syntax error near unexpected token else
Run Code Online (Sandbox Code Playgroud)

我应该怎么做才能修复它?另一个问题是如何在 Visual Studio Code 中格式化我的 shell 脚本,我在 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
Run Code Online (Sandbox Code Playgroud)

ter*_*don 7

您收到错误是因为您的 if/elses 不平衡。sh 脚本中 if/else 的语法是:

if condition 
then
    do something
else
    do something else
fi
Run Code Online (Sandbox Code Playgroud)

每个都if需要由一个fi. 接下来,您将所有文件存储在一个字符串变量中:

files=$(find $filesdir -name '*.txt.gz' -type f -mmin -1)
Run Code Online (Sandbox Code Playgroud)

这意味着如果您的find命令返回如下内容:

$ find . -name '*.txt.gz' -type f
./file2.txt.gz
./file1.txt.gz
Run Code Online (Sandbox Code Playgroud)

那么你的变量的内容将是:

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

但是随后您检查是否存在具有该名称的单个文件:

if [ -f "$files" ]; then
Run Code Online (Sandbox Code Playgroud)

这永远不会是真的,因为你没有一个名字是字面意思的文件,./file2.txt.gz\n./file1.txt.gz即使你有,它也会被包含在结果中。在任何情况下,您已经知道它们是文件并且它们存在,因为这就是find命令正在执行的操作,从而使此测试更加不必要。

您还有很多不必要的变量,您正在设置day_of_month=1然后使用if [ "$day_of_month" == "1" ]它是毫无意义的,因为这总是正确的。numFilesReceived和相同count。我不明白你想用这两个做什么,所以我猜你想设置count一个非 0 值,然后如果文件数与该值匹配则退出。我也不明白这是什么意思day_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

Run Code Online (Sandbox Code Playgroud)

我怀疑这并不是你真正需要的,但我希望它可以作为一个起点。如果您需要更多帮助,请提出一个新问题,但请向我们提供脚本应该做什么的详细信息,以便我们可以更好地帮助您。