watch
is an external program that starts a new program every time interval.
In your case, neither the started default shell sh
nor the explicitly started bash
can know about your function f
– it's not being passed to them.
You include the function definition in what you run. For example, you could write
#!/bin/bash
function f() {
date
}
f
into a text file "myscript.sh", make it executable and run it with watch ./myscript.sh
.
Alternatively, you could also
function f () {
…
}
typeset -fx f
# ^---------- modify the type of a name
# ^----- work only on functions
# ^---- export to environment
watch -x bash -c "f"
# ^-------- use `exec` rather than `system` to start bash;
# makes no sense to start a shell from a shell you
# only start to start a shell (but omitting -x has
# no downside other than launching an unnecessary
# middle layer of `sh`)
to export the function declaration to an environment variable and thus make it known to bash as launched from watch
, as subprocesses inherit environment variables.
I'd recommend you go with the script option - less confusing, and it doesn't mess with the environment, which might have surprising side effects. It has no performance benefits: in both cases, the shell parses the source code of your function declaration in the new subshell.
Lastly, you could do without watch
:
while true ; do
tput clear # to clear the screen
f
sleep 1
done
tput clear
will clear the scroll buffer; if you had anything on that previously, you might want to save it before.