I have a command that lists the ten most recently changed files, excluding a couple of directories:
```bash
find -not ( -path './snap/firefox/common' -prune ) -not ( -path './.cache' -prune ) -type f -mmin -1 -printf "%C+ %pn" | sort -n | tail -10
```
It works when placed in a script, so I can run it with `watch last_change` and even create an alias for that. However, when I define the command as a Bash function instead:
```bash
function what-changed() {
find -not ( -path './snap/firefox/common' -prune ) -not ( -path './.cache' -prune ) -type f -mmin -1 -printf "%C+ %pn" | sort -n | tail -10
}
watch what-changed
```
`watch` reports that it cannot find `what-changed`, even though the function runs normally when called directly in my shell. Why is the function unavailable to `watch`, and what is the best way to run this command repeatedly?
5 Answers
Exporting a function with `export -f what-changed` can make it available to child Bash processes, but it will not reliably solve this particular case because `watch` commonly uses `/bin/sh`, not Bash. A Bash function is not a standalone executable, and `/bin/sh` generally cannot import Bash’s exported-function format. A script or a quoted command is more portable.
If you want to avoid the quoting mess, use a loop instead of `watch`:
```bash
while true; do
clear
find -not ( -path './snap/firefox/common' -prune ) -not ( -path './.cache' -prune ) -type f -mmin -1 -printf '%C+ %pn' | sort -n | tail -10
sleep 5
done
```
This runs directly in your current shell, so functions work normally. You can also use `while date; do ...; sleep 5; done` if you want each refresh to show the current time.
You can also pass the entire pipeline to `watch` as one quoted command, for example:
```bash
watch "find -not ( -path './snap/firefox/common' -prune ) -not ( -path './.cache' -prune ) -type f -mmin -1 -printf '%C+ %p\n' | sort -n | tail -10"
```
Quoting the whole command keeps the pipe characters from being interpreted by your interactive shell. The inner `printf` quotes need to be adjusted or escaped so they survive until the command is evaluated by `watch`.
A function normally exists only inside the current shell process. `watch` starts a separate command, usually by invoking `sh -c`, so it cannot see functions, aliases, or other definitions that only exist in your interactive Bash session. The simplest solution is to keep the command in an executable script and run that with `watch`.
A file-monitoring tool such as `inotifywatch` is another option if the goal is to react to filesystem events rather than periodically refresh a listing. It is useful for event tracking, but it does not produce exactly the same continuously refreshed view as `watch`, so a loop or script is probably a better match here.

Related Questions
Can't Load PhpMyadmin On After Server Update
Redirect www to non-www in Apache Conf
How To Check If Your SSL Cert Is SHA 1
Windows TrackPad Gestures