更新:
我正在研究一个模块化的shell脚本,该脚本在不同级别的子进程中调用usage()
。脚本sample.sh
的结构类似于以下内容:
sample.sh
├─ ...
├─ usage()
├─ awk
├─ usage()
├─ ...
usage()
显示有关如何使用脚本的简要信息(例如,可用的参数及其说明)。首次执行时,usage()
显示在脚本的开头。usage()
调用的其他条件的示例包括:
awk
无法验证来自stdio
或文件的输入收到参数
--help
发生其他用户派生的故障
我想从 shell 及其直接子进程调用相同的函数usage()
awk
。
原始问题:
函数,usage()
sample.sh
根据需要打印其打印语句。
$cat sample.sh
#!/bin/sh
awk '
BEGIN {
usage()
}
function usage() {
print "function inside of awk"
}
'
$./sample.sh
function inside of awk
为了从awk
中取出usage()
并将其作为sample.sh~
中的本地函数,我尝试了:
$cat sample.sh~
#!/bin/sh
usage() {
print "function outside of awk"
}
awk '
BEGIN {
usage()
}
'
$./sample.sh~
awk: calling undefined function usage
source line number 3
正如我们观察到的,我们收到错误消息,指出sample.sh~
中的"未定义的函数用法"。我应该如何改进它?
我找到了一种从awk调用函数的方法
将下面的代码放在一个文件中,例如调用它 a.sh
$ cat a.sh
usage() {
print "function outside of awk"
}
$ chmod +x a.sh
然后你可以在awk中调用该函数
#!/bin/sh
awk '
BEGIN {
system(". a.sh;usage")
}'
使用bash
时,另一种选择是使用export -f
导出 shell 函数,然后通过system()
调用awk
可以使用它:
#!/usr/bin/env bash
usage() {
echo "function outside of awk"
}
# Export the usage() function.
export -f usage
awk '
BEGIN {
system("/usr/bin/env bash -c usage")
}'
请注意,awk
调用带有system()
的sh
,这可能是也可能不是bash
- 如果它是bash
(例如,在 OSX 上),你并不严格需要/usr/bin/env bash -c
部分,但保留它应该让它在大多数平台上工作(有 bash)。
子进程不能调用父进程中的函数,反之亦然。甚至不是同一种语言。
您可以做的是启动包含awk脚本的shell脚本的另一个实例。例如,将其保存在名为./script.sh
的脚本中:
#!/bin/sh -e
usage() {
echo usage: ...
exit 1
}
test "$1" = --usage && usage
awk -v usage_script="$0" '
function usage() { system(usage_script " --usage") }
BEGIN {
usage()
}'
使其可执行,并按./script.sh
运行。在此脚本中,内部awk
脚本中的usage
函数只是使用--usage
脚本重新运行包含的 shell 脚本。请记住,这里将有 3 个进程:shell -> awk -> shell。不可能在单个进程中执行此操作。
原答案
如果将usage
函数定义移到awk
之外,则无法从内部执行是正常的。如果要执行awk
命令,则必须在awk
解释器内部,并且只能使用内部定义的内容。
请注意,确定这是否是您要查找的内容,但您可以将函数定义移动到另一个awk
文件并awk
处理它,例如:
cat <<EOF > functions.awk
function usage() {
print "function in functions.awk"
}
EOF
awk -f functions.awk -e '
BEGIN {
usage()
}
'