0

I'm trying to get the disk usage of some sites on a server using the script below, but I'm getting this error whenever I try to run it:

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

I can't see any syntax errors, but I'm obviously doing something wrong. Can anyone tell me what's going on?

Here's my code:

#!/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

Side Note: For the section that I haven't written yet, can anyone tell me how I should go about saving the names of all the folders in the current working directory to an array? I've heard that parsing the output of 'ls' is a bad idea, so I'm looking for an alternative to that if anyone has one.

Thorium
  • 191
  • 1
  • 14
  • You are missing spaces before your closing `]` in those `[` tests. You are also missing a final `done` in that last block. Run your code through http://shellcheck.net to find these (and other issues). You also aren't looping over the array contents with `for y in paths_array` that just loops over the string `paths_array`. – Etan Reisner May 01 '15 at 01:57

1 Answers1

2

What you have is really close - you just have a few different small syntax errors in play here.

The syntax errors:

  1. You weren't closing your last for loop with done - hence the syntax error on fi: the interpretor was thinking it was still in the loop.
  2. You dropped the $ at the beginning of the variable names in the if statements (e.g. args_length vs $args_length. As a result, bash is interpreting that as a string - args length - instead of the value of the args_length variable.
  3. You were putting spaces around =. In bash, when you assign a value to a variable, there can't be spaces around =. Instead, it should always be like: name="value".
  4. You were missing spaces before your closing brackets (]) in your if statements.

This code works:

#!/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

Which outputs:

Calculating disk usage for all sites...

These sorts of errors in bash are really common and can be hard to pin down, so when they occur just take it one step at a time, reread your code, and try to understand the errors you're getting.

rickcnagy
  • 1,774
  • 18
  • 24
  • What `-eq` and `-lt` issues did you see? The only problems I see on those lines are the spacing problem and the missing `$` to actually use the variable contents. I actually disagree that `[[` is safer **especially** in the context of numerical tests. The behavior of `[[` with numerical tests is **highly** surprising as far as I'm concerned. For example the tests here went from throwing an error (`[ args_length -lt 1 ]`) to silently comparing the value `0` against the right-hand side of the expression `[[ args_length -lt ` ]]`. That's not "safer" or "less surprising" to me. – Etan Reisner May 01 '15 at 02:08
  • @EtanReisner you're totally right - thanks! I missed that, and `[[` was letting that fail silently. Edited my answer. And interesting point about `[[` being *less* safe - I think I agree now... – rickcnagy May 01 '15 at 02:13
  • In general `[[` **is** safer. I agree with that for the most part. It just happens that specifically with numeric tests it has a, to my mind, **very** peculiar and unfortunate behavior. – Etan Reisner May 01 '15 at 02:19
  • Thank you, this is perfect! Can anyone help me with the request at the end of my post? – Thorium May 01 '15 at 02:35
  • No problem @Thorium! Regarding the second request - it's probably neater if you ask it as a second question, since you'll get more focused responses and then in the future, others can more easily search for that exact issue. – rickcnagy May 01 '15 at 02:37
  • @Thorium `dirarr=(*); declare -p dirarr` – Etan Reisner May 01 '15 at 02:44