我正在开发一个模块化shell脚本,它在不同级别的子进程中调用usage()
。脚本sample.sh
的结构类似于:
sample.sh
├─ ...
├─ usage()
├─ awk
├─ usage()
├─ ...
usage()
显示有关如何使用脚本的简要信息(例如,可用参数及其描述)。第一次执行时,脚本开头会显示usage()
。 usage()
调用的其他条件示例包括:
awk
无法验证来自stdio
或文件的输入
参数--help
发生了其他用户派生的故障
我想从shell及其直接子进程usage()
调用相同的函数awk
。
usage()
的{{1}}函数根据需要打印其print语句。
sample.sh
要从$cat sample.sh
#!/bin/sh
awk '
BEGIN {
usage()
}
function usage() {
print "function inside of awk"
}
'
$./sample.sh
function inside of awk
中取出usage()
并将其作为awk
中的本地函数,我尝试了:
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
中收到错误消息“未定义的函数用法”。我应该如何改进它?
答案 0 :(得分:4)
我找到了一种从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")
}'
答案 1 :(得分:2)
子进程无法调用父进程中的函数,反之亦然。甚至不是同一种语言。
您可以做的是启动包含您的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
运行。在此脚本中,内部usage
脚本中的awk
函数只需使用--usage
脚本重新运行包含的shell脚本。请记住,这里将有3个进程:shell - > awk - >贝壳。在一个过程中无法做到这一点。
原始回答
如果将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()
}
'
答案 2 :(得分:2)
使用bash
,另一个选项是使用export -f
导出 shell函数,然后通过awk
调用将system()
提供给#!/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
请注意,sh
调用system()
bash
,bash
可能是/usr/bin/env bash -c
- 如果是{{1}}(例如,在OSX上),你并不严格需要{{1}}部分,但保留它应该使它适用于大多数平台(有bash)。