【问题标题】:If statement syntax error (BASH) [duplicate]If语句语法错误(BASH)[重复]
【发布时间】:2015-05-01 01:54:36
【问题描述】:

我正在尝试使用以下脚本获取服务器上某些站点的磁盘使用情况,但每当我尝试运行它时都会收到此错误:

args.sh: line 50: syntax error near unexpected token `fi'
args.sh: line 50: `fi'

我看不到任何语法错误,但我显然做错了什么。谁能告诉我这是怎么回事?

这是我的代码:

#!/bin/bash

prefix="/var/www/html/"
suffix=".example.com"
path="$prefix$1$suffix"
args_length="$#"
paths_array=[]
args_array=("$@")

# If there is one argument, calculate disk usage of given site.
if [ args_length -eq 1];
    then echo "Calculating disk usage..."
    output=$(du -sh $path)
    echo "This site is currently using $output"
    exit 1

# If there are no arguments, calculate disk usage of all sites.
elif [ args_length -lt 1];
    then echo "Calculating disk usage for all sites..."
    # I haven't done this part yet!
    exit 1

# If there is more than one site, calculate their disk usage    
elif [ args_length > 1];
    then echo "Calculating disk usage for selected sites..."    
    #Save arguments to sites_array
    for x in args_array; do
        paths_array[x] = args_array[x]
    done
    #Loop through array, creating paths.
    for i in paths_array; do
        site = paths_array[i]
        paths_array[i] = "$prefix$site$suffix"
    done
    #Print out disk usage for each path in array.
    for y in paths_array; do
        output = $(du -sh $paths_array[y]) 
        echo "This site is currently using $output"
fi

旁注:对于我尚未编写的部分,谁能告诉我应该如何将当前工作目录中所有文件夹的名称保存到数组中?我听说解析“ls”的输出是个坏主意,所以如果有人有的话,我正在寻找一种替代方法。

【问题讨论】:

  • 在这些 [ 测试中,您在关闭 ] 之前缺少空格。您还缺少最后一个块中的最终done。通过shellcheck.net 运行您的代码以查找这些(和其他问题)。您也没有使用 for y in paths_array 循环遍历数组内容,它只是循环遍历字符串 paths_array

标签: bash if-statement syntax


【解决方案1】:

你所拥有的是真的接近 - 你只是有几个不同的小语法错误在这里发挥作用。

语法错误:

  1. 您没有使用done 关闭最后一个for 循环 - 因此fi 出现语法错误:解释器认为它仍在循环中。
  2. 您在if 语句中的变量名开头删除了$(例如args_length$args_length。结果,bash 将其解释为字符串 - args length - 而不是 args_length 变量的值。
  3. 您在= 周围放置了空格。在 bash 中,当您为变量赋值时,= 周围不能有空格。相反,它应该始终是:name="value"
  4. 您在 if 语句中的右括号 (]) 前缺少空格。

此代码有效:

#!/bin/bash

prefix="/var/www/html/"
suffix=".example.com"
path="$prefix$1$suffix"
args_length="$#"
paths_array=[]
args_array=("$@")

# If there is one argument, calculate disk usage of given site.
if [ $args_length -eq 1 ];
    then echo "Calculating disk usage..."
    output=$(du -sh $path)
    echo "This site is currently using $output"
    exit 1

# If there are no arguments, calculate disk usage of all sites.
elif [ $args_length -lt 1 ];
    then echo "Calculating disk usage for all sites..."
    # I haven't done this part yet!
    exit 1

# If there is more than one site, calculate their disk usage    
elif [ $args_length -gt 1 ];
    then echo "Calculating disk usage for selected sites..."    
    #Save arguments to sites_array
    for x in args_array; do
        paths_array[x]=$args_array[x]
    done
    #Loop through array, creating paths.
    for i in paths_array; do
        site=$paths_array[i]
        $paths_array[i]="$prefix$site$suffix"
    done
    #Print out disk usage for each path in array.
    for y in paths_array; do
        output=$(du -sh $paths_array[y]) 
        echo "This site is currently using $output"
    done
fi

哪些输出:

Calculating disk usage for all sites...

bash 中的这些错误非常常见,而且很难确定,所以当它们发生时,只需一步一步地重新阅读您的代码,并尝试了解您遇到的错误。

【讨论】:

  • 您看到了哪些-eq-lt 问题?我在这些行中看到的唯一问题是间距问题和缺少$ 以实际使用变量内容。我实际上不同意 [[ 在数值测试的情况下更安全尤其是。就我而言,[[ 在数值测试中的行为非常令人惊讶。例如,这里的测试从抛出错误 ([ args_length -lt 1 ]) 到默默地将值 0 与表达式 [[ args_length -lt ]]` 的右侧进行比较。这对我来说并不“更安全”或“不那么令人惊讶”。
  • @EtanReisner 你是完全正确的 - 谢谢!我错过了这一点,[[ 正在默默地让它失败。编辑了我的答案。还有一点关于[[ 的安全性不太 - 我想我现在同意...
  • 一般来说[[ 更安全。我在很大程度上同意这一点。碰巧的是,在我看来,特别是数字测试,它有一个非常特殊和不幸的行为。
  • 谢谢,这太完美了!谁能帮我解决我帖子末尾的请求?
  • 没问题@Thorium!关于第二个请求 - 如果您将其作为第二个问题提出可能会更简洁,因为您将获得更集中的响应,然后在将来,其他人可以更轻松地搜索该确切问题。
猜你喜欢
  • 2015-03-01
  • 2011-09-22
  • 1970-01-01
  • 2020-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
相关资源
最近更新 更多