6

I'm following the tutorial here: http://bash.cyberciti.biz/guide/If..else..fi#Number_Testing_Script

My script looks like:

lines=`wc -l $var/customize/script.php`
if test $lines -le 10
then
    echo "script has less than 10 lines"
else
    echo "script has more than 10 lines"
fi

but my output looks like:

./boot.sh: line 33: test: too many arguments
script has more than 10 lines

Why does it say I have too many arguments? I fail to see how my script is different from the one in the tutorial.

1
  • Did you the first line #!/bin/bash in your script? Also are you running the script in bash shell or ksh? Commented Jun 12, 2012 at 9:00

3 Answers 3

10

wc -l file command will print two words. Try this:

lines=`wc -l file | awk '{print $1}'`

To debug a bash script (boot.sh), you can:

$ bash -x ./boot.sh

It'll print every line executed.

Sign up to request clarification or add additional context in comments.

4 Comments

@KevinDuke you should add a line echo lines contains $lines so you can see what's going on...
One way to help you in these cases is by using the -x option: "sh -x ./script_name" This prints out the script with the variable values substituted.
wc -l < file will return only one word, though it needs to be trimmed.
awk 'END{print NR}' file will also count lines.
8
wc -l file

outputs

1234 file

use

lines=`wc -l < file`

to get just the number of lines. Also, some people prefer this notation instead of backticks:

lines=$(wc -l < file)

Also, since we don't know if $var contains spaces, and if the file exists:

fn="$var/customize/script.php"
if test ! -f "$fn"
then
    echo file not found: $fn
elif test $(wc -l < "$fn") -le 10
then
    echo less than 11 lines
else
    echo more than 10 lines
fi

1 Comment

This will produce unexpected output if the script has permission issues, or some other error occurs. Probably better to just run wc and abort if it fails, allowing wc to print an appropriate error message (which belongs on stderr). For example: a=$( wc -l < "$fn" ) || exit 1; if test "$a" -le 10; then ...
1

Also, you should use

if [[ $lines -gt 10 ]]; then
    something
else
  something
fi

test condition is really outdated, and so is it's immediate successor, [ condition ], mainly because you have to be really careful with those forms. For example, you must quote any $var you pass to test or [ ], and there are other details that get hairy. (tests are treated in every way as any other command). Check out this article for some details.

2 Comments

In Bash, for integer comparisons, you should use if (( lines < 10 )). The comparison you are showing is a lexical comparison which will fail for $lines with a value of 2, for example.
test and [ are not outdated, just highly abused. But they are much more portable than [[ and ((.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.