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
함수는 해당 함수가 정의된 쉘 내부에 있습니다. 다른 프로그램을 실행하면 해당 프로그램이 쉘인 경우에도 해당 기능을 볼 수 없습니다.
(함수는 서브셸에서 액세스할 수 있습니다. 즉, 실행 중인 셸의 복사본을 만들어 대괄호 안의 항목을 실행하거나 (…)
명령 대체 $(…)
등을 위해 액세스할 수 있습니다. 그러나 별도의 프로그램에서는 액세스할 수 없습니다(예: 를 실행할 때 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 특정 기능이므로 상위 스크립트는 sh가 아닌 bash를 실행해야 합니다.
#!/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 편집이 실패함
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" .