1

Having a slight bit of trouble trying to parse out this one in my head. I'm creating a script in korn shell to find if a file system has at least 5GB. If it does not have 5GB, I want the script to error out.

My code to find the available space is

df -g /u00 | sed -n '2p' | awk '{print $3}'

I am using this in an if statement like

if df -g /u00 | sed -n '2p' | awk '{print $3}' -lt "5.00";
then
#There's less than 5gb
echo "There's less than 5GB, please clear up space to continue"
exit 1
else
echo "Enough space, continuing"
fi

The error I'm getting is

awk: 0602-533 Cannot find or open file -lt.
 The source line number is 1.
Enough space, continuing

Obviously, it's not liking where I'm putting -lt in this, and I assume it's the fact that I'm trying to combine it with awk. Problem is, I'm not sure how to write it to where it won't choke next to the awk statement. Is there a better way to do the compare, or am I passing it to -lt incorrectly?

I've also tried passing it as a variable like

export AWK=df -g /u00 | sed -n '2p' | awk '{print $3}'
if [$AWK -lt "5.00"];
then
#There's less than 5gb
echo "There's less than 5GB, please clear up space to continue"
exit 1
else
echo "Enough space, continuing"
fi

And it doesn't seem to like that either

Nuka Raku
  • 95
  • 1
  • 11
  • Note your first command `if ...` misses the `[ ]`. Regarding the second one, `export AWK=df -g...` is wrong: to run a command you need to say `var=$(command)`. – fedorqui Jun 01 '15 at 14:36
  • Correcting that gives me `export AWK=$(df -g /u00 | sed -n '2p' | awk '{print $3}') if [$AWK -lt "5.00"];` Which gives an error of `[3.50: not found` At least it's passing the value so I'm getting somewhere. – Nuka Raku Jun 01 '15 at 14:39
  • You need a space around `[` --> `if [ "$AWK" -lt "5.00" ]` – fedorqui Jun 01 '15 at 14:43
  • Ah! There we go. That did it. Thanks! – Nuka Raku Jun 01 '15 at 14:48

3 Answers3

1

Using and How to select a particular column in linux df command I would say:

df --output=avail /u00

Since the output will be something like

    Avail
299344672

, you always want the last line. To do this, we can use a trick in awk consisting in using END. This block is executed after reading the file, but it stores the last line that was read, so it is the perfect solution for this case.

There, we perform the logic of field > 5GB (note I get the value by saying 5*1024^3). If this happens, we print 1; otherwise, nothing is printed:

df ... | awk 'END {if ($1 > 1024*1024*1024*5) print 1}')

All together, this can be checked with the if [ -n "$value" ] condition, that checks if $value is empty or not:

if [ -n "$(df --output=avail . | awk 'END {if ($1 > 1024*1024*1024*5) print 1}')" ]; then
    echo "bigger"
fi

From man test:

   -n STRING
          the length of STRING is nonzero

Regarding your solution: export AWK=df -g /u00 | sed -n '2p' | awk '{print $3}' if [$AWK -lt "5.00"];

This cannot work because the syntax is var=$(command). Also, the syntax for an if condition is if [ ... ]; that is, you need a space around [.

All together:

export AWK=$(df -g /u00 | sed -n '2p' | awk '{print $3}')
if [ "$AWK" -lt "5.00"];
Community
  • 1
  • 1
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • Doesn't seem to like that `df --output=avail /u00 df: Not a recognized flag: - df: Not a recognized flag: o Usage: df [-P] | [-IMitv] [-gkm] [-s] [filesystem ...] [file ...]` – Nuka Raku Jun 01 '15 at 14:30
  • Uhms, that is a pity. However, the logic is the same. Just use `$3` and tab as separator in the `END` block. – fedorqui Jun 01 '15 at 14:31
  • This works, but I want to make sure I'm forming the command correctly Editing the first part, I get `if [ -n "$(df -g /u00 | awk 'END {if ($1 > 1024*1024*1024*5) print 1}')" ]; then echo "bigger" else echo "smaller" fi ` So ok it echos correctly if it's smaller, but I don't think I'm passing it correctly because I don't entirely understand what the `AWK` statement is doing. Should I be leaving it as `df` or am I to use it as `df -g`. Both echo smaller, which is correct in my case. – Nuka Raku Jun 01 '15 at 14:45
  • @NukaRaku see my updated answer with explanations and also including what we discussed in the comments below your quesiton. – fedorqui Jun 01 '15 at 15:04
0

For whatever reason, the version of df on my AIX 6 and AIX 7 boxes is very limited and doesn't recognize a lot of the expected fields like --output and -m. Additionally, the output of -g is not very grep friendly.

I ended up using this to determine the percent space used. If I wanted to calculate available space, other columns existed that would provide that information, but percent available meets my needs.

df -v /backup | grep "/"|awk '{print $6}'

df -v has the following columns that I think could simplify the awk commands in the above answer like this:

df -v /backup | grep "/"|awk '{if ($5 > 1024*1024*1024*5) print $5}'

That may only work if you have the version of df I have. I tried running df -v to figure out what it is, but then I realized that just gave me what I'd already seen. :-)

Josiah
  • 2,666
  • 5
  • 30
  • 40
  • The reason `df` on AIX doesn't have these options is that they're specific to the GNU version, which is only commonly available on non-embedded Linux systems. To get (mostly) parseable output from `df`, use `df -P`. – Gilles 'SO- stop being evil' Feb 02 '16 at 21:44
  • I'd accept that, but if I run `man df` on that same system it tells me about at least the `-m` option. When I go to use them it rejects them so the system itself says they exist. Do you have a reason for this? For example `df -P` gets me the response `df: Not a recognized flag: P`. – Josiah Feb 02 '16 at 21:50
  • I have no explanation for `df -P` not being supported. It's been a POSIX requirement for a very long time, and it's documented as far back as AIX 5.3. – Gilles 'SO- stop being evil' Feb 02 '16 at 21:56
  • Yeah, I'll just blame the vendor that set this up and move on since I have a work around. :) – Josiah Feb 02 '16 at 21:58
0

The reason -lt didn't do what you expected is that it's only meaningful for the [ command. It isn't a keyword that you can use anywhere in a shell command.

If you wanted to do a comparison with -lt, you'd need to write it in the form [ "THING1" -lt "THING2" ] where THING1 and THING2 are the two numbers to compare. (The double quotes ensure that THING1 and THING2 aren't broken down into separate words even if you made some mistake and accidentally included non-digit characters.) If you want to use the output of awk in this comparison, use a command susbtitution.

if [ "$(df -g /u00 | sed -n '2p' | awk '{print $3}')" -lt 5 ]; then …

Note that you can only use integers, not floating point numbers. (That may not be true if you use ksh, I'm not sure what ksh version AIX has.)

But awk can do numerical comparisons easily, so it would be simpler to let it do the comparison. Use the exit function to return a chosen status from awk; take care that awk uses 0 for false and nonzero for true, but the shell uses 0 for success and nonzero for failure. Awk can also do the whole data extraction, there's no need to use sed in addition. Furthermore, to get output from df that can be parsed in a (mostly) reliable and portable way, use the -P option.

if df -P -k /u00 | awk 'NR==2 {exit !($4 < 5*1024*1024)}'; then
  echo "Less than 5GB available"
fi
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254