저는 새 패키지를 설치하여 "스스로 업그레이드"할 수 있는 프로그램을 개발 중입니다. 이를 달성하기 위해 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
답변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
-
kill
PID
좋아요, 하지만 아직 끝나지 않았죠? 아니요. 전체 명령 세트를 &
백그라운드 서브셸에 넣어서 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 && exec
exec
{ YOUR | CMD }
이 시점에서 우리는 깨끗한 환경의 새 프로세스 그룹에 있는 새 셸에서 새 스크립트를 실행해야 하며 프로세스가 완전히 완료되는 데 걸리는 시간만 기다려야 합니다.
사실 우리는 너무 철저해서 안전하게 할 수 있습니다.
...exec { wget -O - "${URL}" >"${0}" ; exec "${0}" }