How Not To Write a While Loop
I was running a few long processes recently, and was getting tired of watching it in top. I wanted to run something that would tell me when it quit. I went looking, and found wait, but that only works on processes that are children of the current shell, which wouldn't work in my case.
So I figured I'd just write a bash one-liner. I tried
Think about it. (Don't run it yourself, especially without reading the rest of this post!) yes outputs "y\n" in an endless loop. Wrapping a command in backticks runs that command, and puts its output inline for whatever command it's a part of. Do you see the disaster looming?
When I ran the loop, it started by running yes, saving its (infinite) output. This filled available memory. It then filled available swap. My memory docklet reported "MEM 96% SWP 99%", right before the system stopped responding completely. As a testament to the solidity of Linux, the non-responsive stuff only lasted a little while, after which the system responded to all of the Ctrl-C and "close window" clicks I had been sending it, and all of the offending processes (and a few non-offending ones) disappeared. No system crash.
Anyway, lesson learned, and I ended up writing my one-liner as follows:
which waits for the process to go away, then beeps. Made much more sense than whatever I originally had in mind.
So I figured I'd just write a bash one-liner. I tried
while 1
as my base loop, but that didn't work. I thought (incorrectly) that I had tried while true
already, and found that it didn't work (I hadn't), and got this flash of, well, non-genius:while `yes`
Think about it. (Don't run it yourself, especially without reading the rest of this post!) yes outputs "y\n" in an endless loop. Wrapping a command in backticks runs that command, and puts its output inline for whatever command it's a part of. Do you see the disaster looming?
When I ran the loop, it started by running yes, saving its (infinite) output. This filled available memory. It then filled available swap. My memory docklet reported "MEM 96% SWP 99%", right before the system stopped responding completely. As a testament to the solidity of Linux, the non-responsive stuff only lasted a little while, after which the system responded to all of the Ctrl-C and "close window" clicks I had been sending it, and all of the offending processes (and a few non-offending ones) disappeared. No system crash.
Anyway, lesson learned, and I ended up writing my one-liner as follows:
while test -e /proc/nnnnn; do sleep 5; done; echo ^G
which waits for the process to go away, then beeps. Made much more sense than whatever I originally had in mind.