3

Say I have a function f defined in my bashrc

function f() {
  date
}

I want to run following command to monitor the output watch f. The command failed with "sh: f: command not found". watch bash -c f gives the same.

How to get this watch command working as intended?

1 Answer 1

7

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.

9
  • 1
    It is VERY BAD ADVICE suggesting to use tput clear to "clear the screen" because you didn't also note that it clears the terminal's SCROLL BUFFER - which destroys any history a user was planning to capture from the scroll buffer. Commented Sep 21, 2023 at 4:58
  • Hi @FKEinternet, they said they want to monitor the output of f, which I take as "they want to look at it right now, and not the history". If you think of what monitoring actually means, you'll find yourself thinking of people looking at warning lamps and gauges in for example a power plant control room - and not at the log of the last few hours of gauge readings. Feels to me like relying on a scroll back buffer is generally not optimal. Commented Sep 21, 2023 at 7:35
  • 1
    Still, I'm very thankful for the improvement of my answer and the warning is fair. I shortened your proposed wording a bit and took it. Thanks! Commented Sep 21, 2023 at 7:38
  • @FKEinternet you can run clear or press Ctrl+L to clear the screen without messing up the scroll history
    – phuclv
    Commented Sep 21, 2023 at 7:45
  • @FKEinternet thinking about that, tput clear might have the less-invasive effect of just clearing the current screen, at the expense of risking that setting from before survive. Commented Sep 21, 2023 at 7:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .