셸 스크립트의 중복 실행 문제를 어떻게 해결합니까

4486 단어 shell반복 실행

소개


flock은 파일 잠금 명령으로 Linux 시스템에서 프로세스 간에 임계 자원에 안전하게 접근할 수 있으며, 셸 스크립트에서 논리적 배척성을 제어할 수 있습니다

인스턴스 1


기존 스크립트 a.sh, 내용은 다음과 같습니다.

#!/bin/bash

echo "[`date +'%Y-%m-%d %H:%M:%S'`] begin pid:$$..."

sleep 10

echo "[`date +'%Y-%m-%d %H:%M:%S'`] end pid:$$..."
터미널(터미널 1)에서 flock -xn ./f.lock -c ./a.sh 명령을 실행한 결과 다음과 같습니다.

[tt@ecs-centos-7 lock_test]$ flock -xn ./f.lock -c ./a.sh 
[2020-12-10 10:10:45] begin pid:5359...
[2020-12-10 10:10:55] end pid:5359...
상술한 명령이 실행되는 동안 다른 터미널(터미널 2)을 열고 같은 명령을 실행하면 결과는 다음과 같다.

[tt@ecs-centos-7 lock_test]$ flock -xn ./f.lock -c ./a.sh 
[tt@ecs-centos-7 lock_test]$ 
위의 명령 flock-xn./f.lock -c ./a.sh
  • -x 옵션은 배타적 자물쇠이며, 때로는 쓰기 자물쇠라고도 하는데, 이것은 기본 옵션
  • -n 옵션이 막히지 않습니다. 자물쇠를 가져올 수 없으면 자물쇠의 방출을 기다리지 않고 실패로 돌아갑니다
  • -c 옵션 뒤에 실행 중인 명령
  • 터미널 1에서 flock-xn./실행f.lock -c ./a.sh 명령, f.lock 파일을 잠그고./a.sh 명령, 실행 과정은 10초 정도 지속됩니다(sleep 10문장)
    터미널 2에서 flock-xn./f.lock -c ./a.sh 명령은 터미널 1 명령이 실행되는 동안 실행됩니다. 이 때 터미널 1은 f.lock 파일 자물쇠를 풀지 않았습니다. 게다가 -n 옵션이 막히지 않기 때문에 터미널 2는 f.lock 파일 자물쇠를 기다리지 않고 바로 되돌아옵니다.
    터미널 2 flock-x./f.lock -c ./a.sh 명령은 터미널 1이 f.lock 파일 자물쇠를 놓을 때까지 기다림을 막고, f.lock 파일 자물쇠를 가져와 집니다./a.sh 명령

    인스턴스 2


    실례 1에서 매번 flock-xn 파일 자물쇠-c./a.sh 명령, 그리고 반복적으로 실행할 수 없는 모든 스크립트는 파일 자물쇠를 분배해야 하며, 서로 다른 스크립트는 서로 다른 이름의 파일 자물쇠를 사용해야 한다.
    할 수 있는 방법이 있습니까?a.sh 명령으로 실례 1의 기능을 실현할 수 있습니까?
    있다
    우리는 a.sh를 약간 수정하고, 수정한 후의 내용은 다음과 같다.
    
    #!/bin/bash
       
       
    echo "[`date +'%Y-%m-%d %H:%M:%S'`] 1111 pid:$$...MY_LOCK:${MY_LOCK}"
       
    [ "${MY_LOCK}" != "$0" ] && exec env MY_LOCK="$0" flock -xn "$0" "$0" "$@"
       
    echo "[`date +'%Y-%m-%d %H:%M:%S'`] begin pid:$$...MY_LOCK:${MY_LOCK}"
       
    sleep 10
    echo "[`date +'%Y-%m-%d %H:%M:%S'`] end pid:$$..."
    터미널 1 실행./a.sh 명령, 출력은 다음과 같습니다.
    
    [tt@ecs-centos-7 lock_test]$ ./a.sh
    [2020-12-10 14:11:35] 1111 pid:5944...MY_LOCK:
    [2020-12-10 14:11:35] 1111 pid:5946...MY_LOCK:./a.sh
    [2020-12-10 14:11:35] begin pid:5946...MY_LOCK:./a.sh
    [2020-12-10 14:11:45] end pid:5946...
    터미널 1 명령이 실행되는 동안 터미널 2는./a.sh 명령, 출력은 다음과 같습니다.
    
    [tt@ecs-centos-7 lock_test]$ ./a.sh
    [2020-12-10 14:11:44] 1111 pid:5976...MY_LOCK:
    [2020-12-10 14:11:44]
    새로운 a.sh 스크립트는 원래보다 4, 6 두 줄이 추가되었다
    네 번째 줄은 로그 인쇄
    6 행 설명
    $0은 스크립트 이름입니다. 여기 값은./a.sh
    $@ 는 a.sh 스크립트에 전달되는 모든 매개 변수입니다.
    exec는 현재 프로세스에서 다음 명령을 실행합니다. 현재 스크립트 프로세스가 아직 실행되지 않은 명령은 실행되지 않습니다.[ "${MY_LOCK}" != "$0" ] 판단 MY_LOCK 환경 변수 및 스크립트 이름(a.sh)
    같다
    다른 경우 env MY_LOCK="$0" 명령 및 flock -xn "$0" "$0" "$@" 명령 실행
    env MY_LOCK="$0"환경 변수 설정 MY_LOCK 값은 스크립트 이름입니다.flock -xn "$0" "$0" "$@" 사실 flock -xn ./a.sh ./a.sh 현재 스크립트 이름을 파일 자물쇠로 사용합니다
    인스턴스 2에서./a.sh 명령 이후 6행까지 실행할 때 MY_LOCK 변수가 비어 있으므로 [ "${MY_LOCK}" != "$0" ] 결과는true
    exec 명령은 뒤에 실행되지 않은 명령을 무시합니다. 즉, 현재 셸 프로세스에서 여섯 번째 줄 이후의 명령은 실행되지 않습니다.
    이어서, exec env MY_LOCK="$0" flock -xn "$0" "$0" "$@" 명령, MY_LOCK 변수의 값이 현재 스크립트 이름으로 설정됩니다./a.sh, flock-xn "$0""$0""$@"명령을 실행하면 새 하위 셸에서./a.sh, 따라서 스크립트의 다음 출력에 인쇄된 프로세스 ID는 시작과 다르다
    또한 flock-xn "$0""$0""$@"이전에 env MY_를 실행했기 때문에LOCK="$0",MY_LOCK 변수의 값은./로 설정됩니다.a.sh, 그래서 flock -xn "$0""$0""$@"명령을 다시 실행합니다./a.sh 명령 시,
    스크립트 여섯 번째 줄의 ["${MY_LOCK}"! = "$0"] 결과는false입니다. 여섯 번째 줄의 exec 뒤에 있는 명령은 실행되지 않습니다. 스크립트는 일곱 번째 줄에서 끝까지 실행됩니다. 결과는 8과 12 줄의 로그를 출력합니다.

    총결산


    실례1과 실례2는 스크립트의 중복 집행을 해결하는 두 가지 방식을 제공합니다. 주로 flock 명령을 이용하여 파일 자물쇠를 설정하여 이루어집니다. 실례2의 방식은 더욱 간단합니다. 스크립트의 시작에 [ "${MY_LOCK}" != "$0" ] && exec env MY_LOCK="$0" flock -xn "$0" "$0" "$@" 문장만 추가하면 스크립트를 호출하는 명령은 변하지 않습니다.
    flock 명령에 대한 더 많은 옵션 및 사용법은 manflock을 통해 직접 볼 수 있습니다
    이상은 셸 스크립트의 중복 집행 문제를 어떻게 해결하는지에 대한 상세한 내용입니다. 셸 스크립트의 중복 집행 문제에 대한 더 많은 자료는 저희 다른 관련 글을 주목해 주십시오!

    좋은 웹페이지 즐겨찾기