Bash 내장 exec의 사용 사례/실제 예

Bash 내장 exec의 사용 사례/실제 예

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장기 실행 명령)

    너희 중에

    1. 서브셸 시작(외부 ())
    2. 서브쉘의 PID를 알아보세요. ( $$메인 쉘의 PID가 제공됩니다.)
    3. 시간 초과 후 프로세스를 종료하는 하위 쉘을 분리한 다음
    4. 1단계에서 생성한 서브셸 프로세스에서 명령을 실행합니다.

    이 실행됩니다long-running-command, 그러나 미리 결정된 제한된 시간 동안만 가능합니다. 

  • 이것은 약간 지루하지만 나머지 로그인 세션 동안 루트(또는 다른 사용자)로 수행하기로 결정했다면 가능합니다 exec su.

    실제로 이것이 실제로 유용할 수 있는 시나리오를 상상할 수 있습니다. 원격 시스템에 로그인했는데 어떤 이유로 연결을 중단하고 새 연결을 시작하는 데 문제가 있다고 가정해 보겠습니다. 예를 들어, 원격 시스템에 일정을 따르는 방화벽이 있다고 가정합니다. 연결 시 연결이 허용되며, 기존 연결은 닫히지 않으나 현재 새로운 연결은 허용되지 않습니다.

    원하는 작업을 완료했으며 이제 로그아웃할 수 있습니다. 당신의 친구 Bob이 당신과 함께 방에 있고 원격 시스템에서 몇 가지 작업을 하려고 하지만 연결할 수 없습니다. 따라서 를 입력한 exec su - bob다음 암호 프롬프트가 나타나면 그에게 워크스테이션을 넘겨주십시오. 이제 어떤 프로세스도 UID를 사용하지 않으므로(백그라운드에서 무언가를 실행하지 않는 한) Bob이 파일을 망칠 수 없습니다. 그는 (귀하의 동의와 협력을 통해) 귀하의 연결을 효과적으로 이어받을 것입니다.

    노트:

    • 물론 실행이 허용되지 않으면 작동하지 않습니다 su.
    • 그것은 녹음될 것이므로 누군가에게 동기를 설명해야 할 수도 있습니다. 정책(방화벽 계획)을 우회하고 있으므로 문제가 발생할 수 있습니다.
    • 100% 안전하다고 보장하지는 않습니다. 예를 들어, who귀하의 이름이 계속 표시될 수 있습니다. 일부 (잘못 작성된) 프로그램이 이를 사용하여 Bob이 귀하라고 생각하고 그에게 귀하의 리소스에 대한 액세스 권한을 부여할 수 있다고 생각할 수 있습니다.
    • 시스템이 감사되면 Bob의 작업이 귀하를 대신하여 감사될 수 있습니다.

관련 정보