Bash의 exec 내장 문서에서 다음을 고려하십시오.
exec는 새로운 프로세스를 생성하지 않고 쉘을 대체합니다.
사용 사례/실제 사례를 제공해 주세요. 나는 이것이 무엇을 의미하는지 모르겠습니다.
구글링해서 알아낸 내용은I/O 리디렉션. 더 잘 설명할 수 있나요?
답변1
exec
쉘 스크립트에서 주로 다른 바이너리 실행을 위한 래퍼로 사용되는 경우가 많습니다. 예를 들어:
#!/bin/sh
if stuff;
EXTRA_OPTIONS="-x -y -z"
else
EXTRA_OPTIONS="-a foo"
fi
exec /usr/local/bin/the.real.binary $EXTRA_OPTIONS "$@"
이렇게 하면 래퍼 실행이 완료된 후 "실제" 바이너리가 인계받고 프로세스 테이블에서 동일한 슬롯을 임시로 점유했던 래퍼 스크립트의 흔적이 더 이상 남지 않게 됩니다. "진짜" 바이너리는 그것을 시작한 것의 직계 후손이지 손자가 아닙니다.
귀하의 질문에서 I/O 리디렉션에 대해서도 언급하셨습니다. 이는 완전히 다른 사용 사례이며 exec
셸을 다른 프로세스로 교체하는 것과는 아무 관련이 없습니다. exec
다음과 같이 매개변수가 없는 경우 :
exec 3>>/tmp/logfile
그러면 명령줄의 I/O 리디렉션이 현재 셸 프로세스에 적용되지만 현재 셸 프로세스는 계속 실행되어 스크립트의 다음 명령으로 진행됩니다.
답변2
Java 프로그램의 프로세스 ID(PID)를 가져오기 위해 쉘 exec
내장 함수를 사용했습니다. 현재 Java 내에서 PID를 얻을 수 있는 방법이 있을 수 있지만 몇 년 전에는 그렇지 않았습니다. 프로세스에 자체 PID가 있으면 이를 PID 파일에 기록하여( /var/run/
".pid" 접미사가 붙은 파일 이름 검색) 하이퍼바이저가 실행 중인 프로세스의 PID를 알 수 있도록 하고 동일한 작업의 두 번째 인스턴스를 방지할 수 있습니다. 서버. 다음과 같이 작동합니다.
exec java -cp=YourServer.jar StartClass -p $$
main()
클래스 메소드의 코드는 StartClass
매개변수 구문 분석을 처리하고 자체 프로세스 ID를 찾을 수 있습니다.
답변3
재미삼아 사용자 프로세스 통계 및 제한 사항을 사용하여 시스템 백그라운드에서 다음 프로그램(선택한 구현 언어로 번역됨)을 실행해 보세요.
while(true) fork();
이제 사용이 허용된 프로세스 테이블의 모든 슬롯이 실행 중인 프로그램의 복사본으로 채워졌는데 어떻게 프로그램을 종료할 수 있을까요? kill(1)을 시작하려면 다른 프로세스 슬롯이 필요하지만 해당 슬롯이 없습니다. 쉘 자체를 kill 명령으로 대체하는 것이 확실히 편리할 것입니다...
exec /bin/kill -9 -1
(시스템이 /bin/kill에 kill(1)을 가지고 있다고 가정합니다. "exec`whichkill`-9 -1"이 더 안전할 것입니다.) 이렇게 하면 보낼 수 있는 모든 프로세스에 SIGKILL이 전송됩니다.
(참고: 프로세스 제약 조건으로 인해 항상 쉘의 프로세스 슬롯에 대한 새 로그인이 허용되지 않는 한 시작 쉘에서 로그아웃하지 마십시오. 그렇게 하면 정리가 약간 어려울 수 있습니다. 90년대 초반에는 확실히 로그아웃하지 않았습니다.)
답변4
이는 Bruce가 프로세스 PID를 알아야 하는 예와 유사합니다.
(cmdpid=$BASHPID; (sleep 300; Kill "$cmdpid") & exec장기 실행 명령)
너희 중에
- 서브셸 시작(외부
(
및)
) - 서브쉘의 PID를 알아보세요. (
$$
메인 쉘의 PID가 제공됩니다.) - 시간 초과 후 프로세스를 종료하는 하위 쉘을 분리한 다음
- 1단계에서 생성한 서브셸 프로세스에서 명령을 실행합니다.
이 실행됩니다
long-running-command
, 그러나 미리 결정된 제한된 시간 동안만 가능합니다.- 서브셸 시작(외부
이것은 약간 지루하지만 나머지 로그인 세션 동안 루트(또는 다른 사용자)로 수행하기로 결정했다면 가능합니다
exec su
.실제로 이것이 실제로 유용할 수 있는 시나리오를 상상할 수 있습니다. 원격 시스템에 로그인했는데 어떤 이유로 연결을 중단하고 새 연결을 시작하는 데 문제가 있다고 가정해 보겠습니다. 예를 들어, 원격 시스템에 일정을 따르는 방화벽이 있다고 가정합니다. 연결 시 연결이 허용되며, 기존 연결은 닫히지 않으나 현재 새로운 연결은 허용되지 않습니다.
원하는 작업을 완료했으며 이제 로그아웃할 수 있습니다. 당신의 친구 Bob이 당신과 함께 방에 있고 원격 시스템에서 몇 가지 작업을 하려고 하지만 연결할 수 없습니다. 따라서 를 입력한
exec su - bob
다음 암호 프롬프트가 나타나면 그에게 워크스테이션을 넘겨주십시오. 이제 어떤 프로세스도 UID를 사용하지 않으므로(백그라운드에서 무언가를 실행하지 않는 한) Bob이 파일을 망칠 수 없습니다. 그는 (귀하의 동의와 협력을 통해) 귀하의 연결을 효과적으로 이어받을 것입니다.노트:
- 물론 실행이 허용되지 않으면 작동하지 않습니다
su
. - 그것은 녹음될 것이므로 누군가에게 동기를 설명해야 할 수도 있습니다. 정책(방화벽 계획)을 우회하고 있으므로 문제가 발생할 수 있습니다.
- 100% 안전하다고 보장하지는 않습니다. 예를 들어,
who
귀하의 이름이 계속 표시될 수 있습니다. 일부 (잘못 작성된) 프로그램이 이를 사용하여 Bob이 귀하라고 생각하고 그에게 귀하의 리소스에 대한 액세스 권한을 부여할 수 있다고 생각할 수 있습니다. - 시스템이 감사되면 Bob의 작업이 귀하를 대신하여 감사될 수 있습니다.
- 물론 실행이 허용되지 않으면 작동하지 않습니다