我在test.sh中编写了以下脚本:
#!/bin/sh
compare() {
if [ $1 != root ]; then
echo "Fail" >> CAT1.txt
fi
}
awk -F: '$4 == 0' /etc/passwd | cut -d: f1 | xargs -n1 -i bash -c 'compare "$@"' _
当我执行此脚本时,出现以下错误:
_: compare: command not found
答案1
函数是定义它的 shell 的内部函数。如果您运行另一个程序,该另一个程序将看不到该函数,即使它恰好也是一个 shell。
(可以在子 shell 中访问函数,即当制作正在运行的 shell 的副本来运行括号中的某些内容(…)
或用于命令替换$(…)
等时。但它们不能在单独的程序中访问,例如当您运行时sh -c …
。)
在使用该函数的脚本中定义该函数:
#!/bin/sh
awk -F: '$4 == 0' /etc/passwd | cut -d: f1 | xargs -n1 -i bash -c '
compare() {
if [ $1 != root ]; then
echo "Fail" >> CAT1.txt
fi
}
compare "$@"' _
(我假设这是一个玩具示例,这一切都可以在一个简单的 awk 脚本中完成。)
或者,您可以使用 bash 功能,该功能允许通过环境将函数导出到 bash 的子实例。这是 bash 特定的功能,因此父脚本必须运行 bash,而不是 sh。
#!/bin/bash
compare() {
if [ $1 != root ]; then
echo "Fail" >> CAT1.txt
fi
}
export -f compare
awk -F: '$4 == 0' /etc/passwd | cut -d: f1 | xargs -n1 -i bash -c 'compare "$@"' _
答案2
为什么不使用...?
awk -F: '$4==0 && $1 != root ' /etc/passwd > CAT1.txt
1.1 编辑得到Fail
awk -F: '$4==0 && $1 != root {print "Fail" ; } /etc/passwd > CAT1.txt
获取失败和用户名
awk -F: '$4==0 && $1 != root {printf "Fail %s\n",$1 ; } /etc/passwd > CAT1.txt
分叉新的 bash 时,函数定义会丢失。 Ae @mueh 告诉你,你需要
export -f compare
。
答案3
您应该使用某种分叉逻辑来执行此操作。在脚本的环境中设置一些标记,这肯定会向脚本的子实例证明它们应该做一件事,而父级则做另一件事。通过这种方式,您可以使脚本安全地递归。
#!/bin/sh
case $Z:$P in
("$0:${1:-!$P}")
[ root = "$2" ] ||
! echo Fail
;;(*)
set -a; Z=$0 P=$$
</etc/passwd \
awk -F: '$4 == 0'|
cut -d: -f1 |
xargs -n1 "$0" "$$"
esac >>CAT1.txt
或者,也许使用您的 fds 来进行检查。如果您首先从终端运行脚本,那么......
#!/bin/sh
[ -t 0 ] && {
awk '$4 == 0' |
cut -d: -f1 |
xargs -n1 "$0"
exit
} </etc/passwd >>CAT1.txt
[ root = "$1" ] ||
! echo Fail
但最好的方法实际上是改变孩子的$0
:
#!/bin/sh
[ . = "$0" ] && {
[ root = "$1" ] ||
! echo Fail
}
z=$(head -n5 <"$0")
</etc/passwd \
awk '$4 == 0' |
cut -d: -f1 |
>>CAT1.txt \
xargs -n1 \
sh -c "$z" .