• Uncategorized

About bash : Bash-if-condition-to-check-variable-for-changes-over-time

Question Detail

Wondering if it’s possible to finagle this logic (checking a variable for changes over time and running a loop while true) into a bash if statement or while loop condition. I was hoping for something like:

var=$(du -h *flat*.vmdk)
var2=$(sleep 1 ; du -h *flat*.vmdk)

if [[ $var != $var2 ]]; then
    while true
    do 
        echo -ne $(du -h *flat*.vmdk)\\r
        sleep 1
    done
else
    echo "Transfer complete"
fi

I’ve also played with a while loop, rather than an if then with no luck.

while [ $var != $var2 ] ; do echo -ne $(du -h *flat*.vmdk)\\r ; sleep 1 ; done

But I’m seeing that’s not possible? Or I’m having issues where things are incorrectly getting expanded. I’m open to any solution, although I am limited by a very basic shell (ESXi Shell) where many common unix/shell tools may not be present.

Question Answer

You are doing while [ $var != $var2 ] but never updating any of these variables ..

I would do something like:

function get_size() {
    echo $(du -h *flat*.vmdk)
}

var="$(get_size)"
sleep 1
var2="$(get_size)"

while [ $var != $var2 ]; do
    var=$var2
    var2="$(get_size)"
    echo -ne "$(get_size)\\r"
    sleep 1
done

echo "Transfer complete"

What it does:

  1. Use a function, because when you have to write two times or more a same line, it should trigger a “I should make it a function” in your brain.
  2. Updating $var and $var2 within the while loop, so you don’t check the same exact values each time, but check diff between last value and current one.
  3. Add newlines to your code, because code is done to be read by humans, not machines, humans does not likes one-liners 🙂

I’ve not tested it

Not a generic solution, but if what you need is to wait while file keeps on changing, you can simply monitor it’s modification timestamp with find (taking that this command is available), like that:

while find . -name *flat*.vmdk -newermt $(date --date "-1 second" [email protected]%s)|read
do
    sleep 1
done

echo "Transfer Completed !"

w/o using any variables at all.

I like @zeppelin’s approach and I think I would have used it, but the date command in my environment was limited and I wasn’t looking to invest any more time trying to figure that out. I did go with Arount’s solution with a few modifications as seen below:

get_size() {
    echo $(du -h *flat*.vmdk)
}

update() {
var="$(get_size)"
sleep 2
var2="$(get_size)"
}

update

while [ "$var" != "$var2" ]; do
    update
    echo -ne "$(get_size)\\r"
    sleep 1
done
echo "Transfer complete"

The changes I needed:

  1. ESXi Shell uses sh/Dash so I wasn’t able to use the proposed function get_size() {
  2. For whatever reason, the variables always matched until I created the update function to run in and outside the while loop.

Works well/as expected now. Thank you everyone for your help…hope it helps someone else.

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.