다른 스크립트(B)에 의해 호출되는 쉘 스크립트(A)가 있습니다. 이 스크립트(A)에서는 나머지 스크립트가 제대로 작동하기 위한 준비로 일부 디렉터리를 만들고 일부 파일을 이동했습니다. 스크립트 (A)는 스크립트 (B)에 의해 반복적인 방식으로 호출되며 첫 번째 루프 동안 디렉터리 생성과 파일 이동이 한 번만 발생하기를 원합니다.
스크립트의 일부를 한 번만 실행하려면 어떻게 해야 합니까?
답변1
호출 스크립트에서 호출 스크립트로 이 정보를 전달하는 방법에는 여러 가지가 있습니다. 하나는 매개변수( ./script --init
vs. ./script
) 또는 매개변수 값( ./script --init=0
vs. )을 사용하는 것입니다 ./script --init=1
. 가장 쉬운 방법은 환경 변수를 사용하는 것입니다.
스크립트 B:
init=0
while whatever; do INIT=$((init++)) ./script_A; done
스크립트 A:
[...]
if [ 0 -eq "$INIT" ]; then
: make preparations
fi
[...]
스크립트 A가 스크립트 B의 호출 없이 실행될 수 있는 경우 누락된 변수를 처리해야 합니다( if
물론 명령문 이전).
: ${INIT:=1}
답변2
의존하려면 상대적으로 독특한 환경 품질이 필요합니다. 이는 구현하기 쉽지 않습니다. 특히 루프에서 별도의 스크립트를 반복적으로 호출하고 나타날 때마다 다르게 동작할 것으로 예상하는 경우에는 더욱 그렇습니다.(이 경우 동일한 스크립트의 일부를 사용하지 않는 이유는 무엇입니까?).
그럼에도 불구하고 일반적인 관행은 이러한 작업을 수행하기 위해 잠금 파일 또는 유사한 파일을 사용하는 것입니다. 하지만 그러기 위해서는 독특한 환경이 필요합니다. 다음을 고려하세요:
sh -c 'echo "$PPID" "$$"
for i in 1 2 3 4 5
do sh -c "echo \"\$PPID\""
done'
산출
25711 28929
28929
28929
28929
28929
28929
환경 변수에 pid를 제공하기 위해 호출자가 의존할 수 있다면 $PPID
그것이 바로 여러분에게 필요한 것일 수 있습니다. 예를 들어:
#!/bin/sh
#script a
LOCKDIR=${TMPDIR:-/tmp}/${0##*/}.$PPID
init() { mkdir "$LOCKDIR" || exit
# do other initialization tasks
}
loop() { : do the iterable tasks here; }
[ -d "$LOCKDIR" ] || init
loop
...그리고...
#!/bin/sh
#script b
a='/path/to/script/a'
for stuff in $things
do "$a" "$stuff"
done
rm -rf "${TMPDIR:-/tmp}/${a##*/}.$$"
하지만 진지하게, 저는 이와 같은 작업을 수행하는 것이 좋은 생각인 상황을 많이 접하지 못했습니다. 다른 쉘 스크립트를 반복적으로 호출하고 해당 환경에 의존해야 한다면 다음 .
의 내용을 소스로 얻을 수 있습니다. 스크립트를 현재 쉘에 넣고 그런 식으로 실행하십시오. 나는 이렇게 할 것이다. 즉, 만약 내가 그랬다면매우내가 실행 중인 스크립트가 안전하게 작성되었는지 확인하세요.
답변3
if 문에 대한 트리거로 줄 번호를 사용한 트리거 텍스트 파일을 만든 다음 if 문 내부의 텍스트 파일을 편집하여 더 많은 줄을 추가했습니다. 이렇게 하면 반복 횟수에 관계없이 if 문은 한 번만 실행됩니다. 아주 간단한 코드로 해결 가능합니다. Trigger.txt n=$(wc -l > Trigger.txt fi를 터치하세요.