0

I have a barebones FreeBSD system with only a terminal. I would like to monitor zpool status every 15 seconds or so. Usually on "regular" systems I would use watch -n15 but this is not available here.

I don't know if I want to go into installing new programs on an important and possible fragile host. But I'm open to do it if it's really simple, I have heard about a replacement called cmdwatch.

My simple solution to monitoring the program is to use a while loop, namely:

while :; do zpool status && sleep 15; done

This ostensible works. However, now I can't break the loop using Ctrl + C, which is a big nuisance. I can use Ctrl + Z to put the loop in the background, call ps to get the PID and then kill -9 the program. Regular kill doesn't work.

So this is not good enough. For any user who is not me the system looks broken. Another post pointed me to checking that the return code is greater than 128, SIGINT should give 130, like this

while [ 1 ]; do zpool status; test $? -gt 128 && break; done

This works if I run only the sleep 15 command. Chaining more commands together either with ; or && gives the old situation where I can't interrupt the loop.

What do I do?

3
  • Does this machine not have multiple consoles on the physical terminal (Alt+F1; Alt+F2; etc.)? It's been a while since I've used FreeBSD, but I thought this was implemented there. Commented Feb 8, 2017 at 17:00
  • 2
    How is it possible that control-c doesn't work? I've tried to reproduce this on a FreeBSD console with /bin/sh but I failed to do so. Commented Feb 8, 2017 at 17:03
  • What shell are you using? As Mateusz, I cannot recreate this in /bin/sh, or with Bash/ZSH. Also, what version of FreeBSD are you using? Commented Feb 17, 2017 at 12:01

3 Answers 3

1

Add a kill condition:

canary=$(mktemp)
echo "Canary is $canary"
while [[ -f "$canary" ]]; do
    COMMAND
    sleep 15
done &

To break out, kill (rm) the canary.

3
  • This still requires me to Ctrl + Z the program and manually remove this file. I only have a single terminal windows on this host. So this solution doesn't help me. Commented Feb 8, 2017 at 16:38
  • 1
    Use job control and start this in the background. Commented Feb 8, 2017 at 16:42
  • Or background the entire loop. You'll be told where the canary is and can remove it at your leisure. You could even define a function with a static name to do so rather than having to note the name of the temporary file. Commented Feb 8, 2017 at 16:56
0

The GNU watch utility is available for FreeBSD as the gnu-watch port/package.

After having put the loop in the background, just fg and press Ctrl+C.

bash-4.4$  while true; do echo hello && sleep 2; done &
[1] 26130
bash-4.4$ hello
hello
hello
hello
hello
hello

bash-4.4$ fg
while true; do
    echo hello && sleep 2;
done
hello
^C
bash-4.4$

A really simple implementation of the watch utility with a static sleep time of 5 seconds as a shell function:

function watch
{
    while true; do 
        clear
        command "$@"
        sleep 5
    done
}
0

Have you considered using a trap?

#! /bin/sh
trap "break" INT
while :
do
    COMMAND && sleep 15
done
0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.