2

In the sections below, you'll see the shell script I am trying to run on a UNIX machine, along with a transcript.

When I run this program, it gives the expected output but it also gives an error shown in the transcript. What could be the problem and how can I fix it?

First, the script:

#!/usr/bin/bash

while read A B C D E F
do
    E=`echo $E | cut -f 1 -d "%"`
    if test $# -eq 2
    then
        I=`echo $2`
    else
        I=90
    fi
    if test $E -ge $I
    then
        echo $F
    fi
done

And the transcript of running it:

$ df -k | ./filter.sh -c 50
./filter.sh: line 12: test: capacity: integer expression expected
/etc/svc/volatile
/var/run
/home/ug
/home/pg
/home/staff/t
/packages/turnin
$ _
4
  • you can easily see the source of your problem by using the shell debug/trace faciltiiy, set -vx. ( set +vx turns it off). Good luck. Commented May 9, 2015 at 15:02
  • Incidentally, you want to avoid the useless use of echo: simply I=$2 is cheaper, faster, shorter to type, and more robust than I=$(echo "$2") (or the equivalent in backticks that you have which is harder to type with proper formatting here, modulo improper quoting). Commented May 10, 2015 at 7:54
  • @tripleee: Should be I="$2" rather than I=$2 Commented May 11, 2015 at 1:22
  • 1
    @KeithThompson Actually, the RHS of an assignment is handled specially, so the double quotes are not required (but of course, they are harmless). But for consistency, indeed, perhaps I should have included them. Thanks for bringing this up. Commented May 11, 2015 at 3:33

1 Answer 1

2

Before the line that says:

if test $E -ge $I

temporarily place the line:

echo "[$E]"

and you'll find something very much non-numeric, and that's because the output of df -k looks like this:

Filesystem     1K-blocks      Used Available Use% Mounted on
/dev/sdb1      954316620 212723892 693109608  24% /
udev               10240         0     10240   0% /dev
: :

The offending line there is the first, which will have its fifth field Use% turned into Use, which is definitely not an integer.

A quick fix may be to change your usage to something like:

df -k | sed -n '2,$p' | ./filter -c 50

or:

df -k | tail -n+2 | ./filter -c 50

Either of those extra filters (sed or tail) will print only from line 2 onwards.


If you're open to not needing a special script at all, you could probably just get away with something like:

df -k | awk -vlimit=40 '$5+0>=limit&&NR>1{print $5" "$6}'

The way it works is to only operate on lines where both:

  • the fifth field, converted to a number, is at least equal to the limit passed in with -v; and
  • the record number (line) is two or greater.

Then it simply outputs the relevant information for those matching lines.

This particular example outputs the file system and usage (as a percentage like 42%) but, if you just want the file system as per your script, just change the print to output $6 on its own: {print $6}.

Alternatively, if you do the percentage but without the %, you can use the same method I used in the conditional: {print $5+0" "$6}.

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

3 Comments

Oh cool it works. Just one question: Is my problem caused by the header?
@Fahad, almost certainly, yes.
Oh thank you so much. Now I get it. In the first line I get "Use" as well, which is certainly not an integer. Thanks heaps :)

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.