상위 스크립트에 정의된 함수 사용

상위 스크립트에 정의된 함수 사용

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

  1. 왜 사용하지 않습니까...?

    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
    
  2. 새로운 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" . 

관련 정보