假设我在 bashrc 中定义了一个函数 f
function f() {
date
}
Run Code Online (Sandbox Code Playgroud)
我想运行以下命令来监视输出
watch f
。命令失败并显示“ sh: f: command not found ”。
watch bash -c f
给出相同的。
如何让这个 watch 命令按预期工作?
watch
是一个外部程序,每个时间间隔都会启动一个新程序。
在您的情况下,启动的默认 shellsh
和显式启动的shell 都不bash
知道您的函数f
\xe2\x80\x93 它没有被传递给它们。
您可以在运行的内容中包含函数定义。例如,你可以写
\n#!/bin/bash\nfunction f() {\n date\n}\nf\n
Run Code Online (Sandbox Code Playgroud)\n写入文本文件“myscript.sh”,使其可执行并使用watch ./myscript.sh
.
或者,您也可以
\nfunction f () {\n\xe2\x80\xa6\n}\ntypeset -fx f\n# ^---------- modify the type of a name\n# ^----- work only on functions\n# ^---- export to environment\nwatch -x bash -c "f"\n# ^-------- use `exec` rather than `system` to start bash;\n# makes no sense to start a shell from a shell you\n# only start to start a shell (but omitting -x has\n# no downside other than launching an unnecessary\n# middle layer of `sh`)\n
Run Code Online (Sandbox Code Playgroud)\n将函数声明导出到环境变量,从而使 bash 知道从 启动watch
,因为子进程继承环境变量。
我建议您使用脚本选项 - 不那么混乱,并且不会扰乱环境,这可能会产生令人惊讶的副作用。它没有性能优势:在这两种情况下,shell 都会在新的子 shell 中解析函数声明的源代码。
\n最后,你可以不用watch
:
while true ; do\n tput clear # to clear the screen\n f\n sleep 1\ndone\n
Run Code Online (Sandbox Code Playgroud)\ntput clear
将清除滚动缓冲区;如果您以前有过任何相关内容,您可能想先保存它。