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


12

Bash의 내장 실행 파일 문서에서 이것을 고려하십시오.

exec는 새로운 프로세스를 생성하지 않고 쉘을 대체합니다

사용 사례 / 실제 사례를 제공하십시오. 이것이 어떻게 이해되는지 이해가되지 않습니다.

Google에서 I / O 리디렉션 에 대해 발견했습니다 . 더 잘 설명 할 수 있습니까?


답변:


18

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 "$@"

랩퍼의 실행이 완료된 후 "실제"2 진이 인계되고 더 이상 프로세스 테이블에서 동일한 슬롯을 점유 한 랩퍼 스크립트의 흔적이 더 이상 없습니다. "진짜"바이너리는 손자 대신에 시작된 것의 직접적인 자식입니다.

질문에 I / O 리디렉션도 언급했습니다. 이것은 매우 다른 유스 케이스이며 exec쉘을 다른 프로세스로 바꾸는 것과는 아무런 관련이 없습니다. 때 exec인수가 없기 때문에 좋아한다 :

exec 3>>/tmp/logfile

그러면 명령 행의 I / O 재 지정이 현재 쉘 프로세스에 적용되지만 현재 쉘 프로세스는 계속 실행되고 스크립트의 다음 명령으로 이동합니다.


1
두 경우가 모두 관련되어 있다고 말할 수도 있습니다 exec. 쉘은 자식 프로세스에서 작업을 수행하지 말고 명령을 실행하거나 리디렉션을 수행하도록 지시하지만 동일한 프로세스에서 수행합니다.
Stéphane Chazelas

5

exec내장을 사용하여 프로세스 ID (PID)를 Java 프로그램으로 가져 왔습니다 . Java 내부에서 PID를 얻는 방법이있을 수 있지만 몇 년 전에는 없었습니다. 프로세스에 자체 PID가 있으면 /var/run/관리 프로그램이 실행중인 프로세스의 PID를 알고 두 번째 인스턴스를 방지 할 수 있도록 PID 파일에 해당 파일을 쓸 수 있습니다 ( '.pid'접미사가있는 파일 이름 찾기 ). 같은 서버에서 실행되지 않습니다. 다음과 같이 작동합니다.

exec java -cp=YourServer.jar StartClass -p $$

main()클래스 메소드의 코드 StartClass는 인수 구문 분석을 처리하고 자체 프로세스 ID를 찾을 수 있습니다.


2

재미있게, 사용자 프로세스 계정 및 제한이있는 시스템에서 백그라운드에서 다음 프로그램 (선택한 구현 언어로 번역됨)을 실행하십시오.

while(true) fork();

프로세스 테이블에서 사용할 수있는 모든 슬롯이 실행중인 프로그램의 사본으로 가득 차면 어떻게 종료 하시겠습니까? kill (1)을 시작하려면 가질 수없는 다른 프로세스 슬롯이 필요합니다. 쉘을 kill 명령으로 대체하는 것이 편리합니다 ...

exec /bin/kill -9 -1

(시스템이 / bin / kill에 kill (1)을 가지고 있다고 가정합니다. "exec`that kill` -9 -1"이 잠재적으로 더 안전합니다.) SIGKILL을 가능한 모든 프로세스에 보냅니다.

(참고 : 프로세스 제한으로 인해 항상 새 로그인 프로세스 쉘에 프로세스 슬롯이 허용되지 않는 한 실행 쉘에서 로그 아웃하지 마십시오. 그렇지 않으면 정리하기가 약간 더 어려울 수 있습니다. 90 년대 초반


3
(1) exec이 상황에서 유용한 명령을 실제로 보여 주면이 대답이 약간 더 좋습니다 . (2)이 답변은 다소 구식입니다. 이 kill명령은 수년 동안 bash에서 기본 제공 명령으로 사용되었습니다.
G-Man은 '복귀 상태 모니카'

@ G-Man : 당신은 당신의 아이템 (2)가이 답변을 OP에 대한 정확한 응답으로 만든다는 것을 알고 있습니까?
Eric Towers

아니요, 이해가되지 않습니다. 나에게 설명해주세요.
G-Man, 'Reinstate

4
나는 당신을 따르고 있지 않습니다. 이 질문은 모든 bash 내장 명령 의 실제 예를 요구하지 않습니다 . 예를 묻습니다 . 내장 exec이라는 사실은 실제로 kill내장과 관련이 없습니다 exec.
G-Man, 'Reinstate

1
방금 답변을 업데이트했습니다. (1) 무엇을 추측합니까? 프로세스 테이블이 가득 찬 경우 명령 대체 (예 `which kill`:)도 작동하지 않습니다. (2) BTW, $(…)양식이 양식보다 권장 `…`됩니다. (3) 그러나 디렉토리를 추측하는 데 아무런 위험이 없습니다. 실수로를 입력 exec /binn/kill하면 오류 메시지가 표시되고 셸이 사라지지 않습니다. (4) 그러나이 경우에도 디렉토리가 무엇인지에 대해 걱정할 필요가 없습니다 kill입니다.  exec용도는 $PATH단지 일반 명령처럼, 그래서 exec kill …(당신이 가정 작동 /bin검색 경로에).
G-Man, 'Reinstate

1
  • 이것은 프로세스의 PID를 알아야하는 Bruce의 예와 유사합니다.

    (cmdpid = $ BASHPID; (sleep 300; kill "$ cmdpid") & exec long- unning -command )

    당신이

    1. 서브 쉘 (외부 ())을 시작하십시오.
    2. 서브 쉘의 PID를 찾으십시오. ( $$기본 쉘의 PID를 제공합니다.)
    3. 시간 초과 후 프로세스를 종료하는 하위 서브 쉘을 분리하고
    4. 1 단계에서 작성한 서브 쉘 프로세스에서 명령을 실행하십시오.

    이 실행 long-running-command되지만 미리 결정된 제한된 시간 동안 만 실행 됩니다. 

  • 이것은 약간 경박하지만, 나머지 로그인 세션에서 루트 (또는 다른 사용자)가되기를 원한다면 exec su.

    실제로, 이것이 실제로 유용한 시나리오를 상상할 수 있습니다. 원격 시스템에 로그인했는데 어떤 이유로 연결을 끊고 새 연결을 시작하는 데 문제가 있다고 가정하십시오. 예를 들어, 원격 시스템에 스케줄을 따르는 방화벽이 있다고 가정하십시오. 연결했을 때 연결이 허용되었으며 설정된 연결이 닫히지 않지만 현재 새 연결이 허용되지 않습니다.

    원하는 작업을 완료했으며 로그 아웃 할 준비가되었습니다. 친구 인 Bob과 함께 방에 있으며 원격 시스템에서 일부 작업을 수행하려고하지만 연결할 수 없습니다. 따라서 exec su - bob암호를 입력하고 암호 프롬프트가 나타나면 워크 스테이션을 그에게 넘기십시오. 백그라운드에서 무언가를 실행하지 않는 한 UID에 대한 프로세스가 없으므로 Bob은 파일을 엉망으로 만들 수 없습니다. 그는 귀하의 동의와 협력을 통해 귀하의 연결을 효과적으로 인수 할 것입니다.

    노트:

    • 물론 실행이 허용되지 않으면 작동하지 않습니다 su.
    • 기록 될 것이므로 누군가에게 동기를 설명해야 할 수도 있습니다. 정책 (방화벽 일정)을 우회하기 때문에 문제가 발생할 수 있습니다.
    • 100 % 안전하다는 보장은 없습니다. 예를 들어, who아마 당신의 이름을 보여줄 것입니다. 일부 (나쁘게 쓰여진) 프로그램이 Bob을 당신이라고 생각하고 그에게 당신의 자원에 접근 할 수있게하기 위해 그것을 사용할 것입니다.
    • 시스템이 감사를 수행하는 경우 Bob의 조치가 사용자 이름으로 감사 될 수 있습니다.

실제로 대부분의 쉘 에서 쉘은 서브 쉘의 마지막 명령에 대해 포크를 최적화 (a;b)하는 것과 이미 동일 (a;exec b)합니다. 유일한 예외는 bash및 것 같습니다 mksh. 사용하면 exec이를 보장하는 데 도움이됩니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.