Thanks I already extensively rewrote the script based on feedback. You
bring forth some other good points.
>> function getFreeGB {
>> df -BG $(dirname $1) | \
>> tail -n 1 | \
>> awk '{print substr($4, 1, length($4) - 1)}'
>> }
>
> In scripting the backslashes as a line continuation are a bad concept
> since you don't see whether there's whitespace characters (other than
> the newline character) there. Specifically a final pipe symbol doesn't
> need any explicit textual line continuation so it can be anyway just
> omitted.
I know that you have to be careful that the backslash is the last
character on the line, but I find it important that lines (if
possible) are less as 80 characters.
I did not know that the final pipe symbol does not need an explicit
context. That is going to make my live easier.
> Since you want only the last line of the df output you can let awk do
> that job; at the end of processing the last processed input line is
> still available in the END section, a simple change
I was wondering about that, wanted to verify it, but 'needed' to
publish something fast.
> df -BG $(dirname $1) |
> awk 'END {print substr($4, 1, length($4) - 1)}'
>
> and since you want to strip just the numerical part from the field $4
> you can simplify that substr/langth by doing numeric "type casting"
>
> df -BG $(dirname $1) |
> awk 'END {print 0+$4}'
That is also an huge improvement.
I had already added that the partition should be on /dev and that a
warning is given when the file system is btrfs.
So the function has become:
function getFreeGB {
fields="$(df -BG -T $(dirname $1) | awk 'END { print $1, $2, 0 + $5 }')"
read dev fs gb <<< "${fields}"
# Check $dev starts with /dev/
if [[ ! $dev =~ ^/dev/.* ]]; then
giveError "File system is not on /dev ($dev)" 5
fi
if [[ $fs == btrfs ]] ; then
echo "This script is not guaranted to work with btrfs" >&2
fi
echo $gb
}
> Below I am wondering why you are not consistently using braces when
> expanding variables; we see ${0} and $2, and we see ${_gbFree} and
> $_gb. I think this is confusing for folks that are learning shell -
> as I understood that this was the (or one) intention of your post.
> Whatever you prefer, but mixing is not a good thing as a paragon.
Oops, that I used ${0} was certainly wrong. :'-(
Let me explain. In the past people where really annoyed by me using
braces. "It is not necessary." But there are some cases where they are
important. That is why I decided that when the length of a name is not
more as 4 characters long I will not use braces and otherwise I will.
But I should explain that.
> Since you're using a modern shell like bash (and obviously don't
> restrict to POSIX)
I am a bit on the fence with that. In a way I like to confirm to
POSIX. But not rigorously. For example I use long options, but
mentions what the corresponding short ones are. Handy for people that
have a POSIX compliant awk.
> I wonder why you don't use arithmetic expressions. Instead of
>
> if [[ ${_gbFree} -le $(($_gb * 4)) ]]
>
> there's the much clearer
>
> if (( _gbFree <= _gb * 4 ))
Correct, implemented.
> Finally, and especially if a variable is named "File", I'd quote the
> variable expansions ("${_swapFile}"), as a paragon for the learning
> folks, but also as an actual safety measure (since it's initialized
> by the caller through $1, which can contain white-space characters).
You are right again. I 'always' say I want to use 'unnecessary'
checks, because I am (hopefully) not the only person that uses my
scripts. But I dropped the ball here. :'-(
> Note: I haven't read the article behind your posted link, and I also
> haven't inspected every line of your code; my comments are just from
> a few quite obvious observations in the posted shell source code.
It is very much appreciated.