1분보다 빠른 실행 지연?

1분보다 빠른 실행 지연?

저는 새 패키지를 설치하여 "스스로 업그레이드"할 수 있는 프로그램을 개발 중입니다. 이를 달성하기 위해 at명령을 사용하여 앞으로 1분 후에 쉘 스크립트를 실행하고 쉘 스크립트가 패키지를 설치하도록 지정합니다. 나는 그것이 다음 순간에 실행되기를 진심으로 희망하지만 매뉴얼 페이지에서 읽은 내용에 따르면 이것이 내가 할 수 있는 최선인 것 같습니다. 더 엄격한 해상도로 이를 수행할 수 있는 방법이 있습니까?

답변1

프로그램을 실행하고 즉시 업데이트를 실행하도록 하는 것이 더 쉽습니다(또는 정말로 필요한 경우 약간의 지연을 두고 절전 모드로 전환될 수도 있습니다).

이것이 스크립트 자체(예: bash)에 있는 경우 업데이트 스크립트를 직접 호출하십시오(출력을 리디렉션할 수도 있음).

update-my-thingy < /dev/null > /dev/null 2>&1

프로그램에 있는 경우 언제든지 system() 호출을 사용하여 동일한 작업을 수행할 수 있습니다.

system("update-my-thingy < /dev/null > /dev/null 2>&1");

답변2

몇 초 동안 기다리는 스크립트를 포크합니다.

{ sleep 5; update-my-program; } &

프로그램이 종료된 후 즉시 업그레이드하는 것이 목표이고 이전에는 업그레이드하지 않는 것이라면 다음을 호출하여 프로그램 종료를 예약하세요.execve바꾸다exit. 시스템 execve호출은 현재 프로그램을 다른 프로그램으로 대체합니다. C에는 인수 전달 방법에 따라 여러 가지 변형( 등) execl이 있습니다 . execp쉘에서 해당 내장은 exec.

답변3

프로그램이 수행하는 작업에 따라 다릅니다. 데몬의 경우 다음과 같이 수행됩니다.

  • 실행 파일의 수명 확인
  • 기간이 프로그램 시작 시간보다 작으면 실행 파일을 새 버전으로 덮어씁니다.
  • 이런 경우에는 해야 할(또는 하지 말아야 할) 작업이 없을 때까지 기다리십시오.
  • exec()새 바이너리로 프로그램을 직접 다시 시작하세요.

답변4

이것은 까다 롭습니다. 먼저, 예방 조치로 스크립트 시작 부분에 함수 호출을 넣고 끝까지 호출하지 마세요.

% killmenow() { ... }
...
% killmenow
EOF

이는 현재 스크립트의 모든 내용을 완전히 읽고 메모리에 복사했는지 확인하는 가장 좋은 방법입니다. 그냥 말하는 거야.

이제 대답하려고 합니다...

POSIX는 jobs이러한 작업을 위한 유틸리티를 지정합니다. 구체적으로는 , wait, 의 조합이 가장 안전하다고 trap생각 합니다. kill가능한 한 깔끔하게 작업을 진행하려면 다음을 사용할 수 있습니다.newgrp다시 말하지만, 이는 exec유전되는 특성 측면에서 매우 유사하지만 이 경우에는 매우 중요할 수 있습니다 process id.

좋아, 많이 들리는 건 알지만 결국에는 볼 것이 많지 않습니다.

% suicide() { _me="${1}" ; ( 
>> trap 'wait "${_me}" && set -- &&\
>>> eval `newgrp && exec { YOUR | CMD | HERE }`' INT &&\
>> kill -s INT "-${_me}"
>> ) & }
...
% suicide "${$}"

좋습니다. 작업 흐름은 다음과 같습니다.

  • suicide먼저 전체 스크립트를 로드하고 실행합니다. 마지막 줄까지 이를 수행하지 않기 때문에 확신합니다 .
  • suicide복사본을 전달한 process id다음 에 저장합니다 $_me. 이 경우 내부에서 쉽게 가져올 수 있지만 suicide다른 곳에서 사용할 수도 있습니다.
  • trap서브셸에서는 스캔을 호출 trapped '$cmd'하고 소문에 대한 호출을 모니터링하도록 지시합니다 INT.
  • kill물론 우리가 마지막 요청을 할 수 있도록 모든 준비가 되어 있습니다. kill우리에게 전달되었을 뿐만 아니라 전체 프로세스 그룹이 이를 수신하도록 지정했습니다. 두려워하지 마십시오 - 전체 시스템이 미쳐버리지 않는 한 - 지금은 죽일 수 없어야 하는 어떤 것도 죽일 수 없습니다. 또한 매개변수를 지정할 필요가 없습니다. 단지 철저하게 하고 싶었을 뿐입니다.INTERRUPT SIGNAL$_me-$_my$_me$_me-killPID

좋아요, 하지만 아직 끝나지 않았죠? 아니요. 전체 명령 세트를 &백그라운드 서브셸에 넣어서 trap계속 응답하고 응답할 수 있도록 합니다 INT.

  • 그것을 받은 후 INT지금 trap평가하십시오 'quoted argument'. 해당 문자열에 있는 모든 항목은 지금만 꺼내지고 있다는 점을 기억하는 것이 중요합니다.
  • $_me다른 곳에서 해결해야 할 답변이 없는 질문이 있는 경우를 대비해 trap먼저 전화해 ​​주세요.wait$_me그 위에필요한 경우에만 입장을 고수합니다..
  • 준비가 완료되면 나머지를 닦아내고 사업을 시작했습니다 env $vars.set --

newgrp실행되도록 설계되었습니다 interactive shell. 이와 같이 깨끗한 이스케이프 프로세스를 반드시 제공할 필요는 없습니다. 실제로 시스템에 group비밀번호가 필요한 경우(그러면 안 됨) 이 비밀번호는 작동하지 않으며 이제 사라집니다.

나는 이 방법을 부른다.교활한아래에서는 POSIX 가이드에서 직접 가져옵니다.

이에 대한 일반적인 구현은 newgrp현재 셸이 로 exec자신을 덮어쓴 newgrp다음 그룹을 변경한 후 새 셸로 자신을 덮어쓰는 것입니다.

그럼 다음 문단에서...

newgrp 명령은 대화형 터미널에서만 사용할 수 있습니다. 애플리케이션을 지원하는 데 유용한 인터페이스를 제공하지 않습니다.

따라서 교활한 부분은 eval저장 및 재사용과 같은 이런 종류의 작업에 매우 능숙할 수 있다는 것 입니다 "$@". 하지만 나중에는 아마도...

  • 대신 대화형 프롬프트에서 다음 명령만 가져오는 다른 프로세스를 먼저 로드하는 명령문을 간접적으로 사용한 다음 몰래 eval백도어 를 추가합니다 .newgrp && execexec{ YOUR | CMD }

이 시점에서 우리는 깨끗한 환경의 새 프로세스 그룹에 있는 새 셸에서 새 스크립트를 실행해야 하며 프로세스가 완전히 완료되는 데 걸리는 시간만 기다려야 합니다.

사실 우리는 너무 철저해서 안전하게 할 수 있습니다.

...exec { wget -O - "${URL}" >"${0}" ; exec "${0}" }

관련 정보