실행 파일을 덮어쓰면 원본 실행 파일을 실행하는 프로세스에 영향이 있습니까?

실행 파일을 덮어쓰면 원본 실행 파일을 실행하는 프로세스에 영향이 있습니까?

실행 파일이 프로세스에서 실행 중일 때 실행 파일을 덮어쓰거나 삭제한 후 다시 설치하여 다시 생성하면 프로세스가 새 실행 파일을 다시 실행합니까?

질문에 대한 대답은 다음에 따라 다릅니다.

  • 실행 파일이 프로세스 내에서 서비스/데몬으로 실행됩니까?

  • Linux, Unix 등과 같은 운영 체제...?

  • 재설치는 설치 프로그램 파일(예: Ubuntu, Windows)을 통해 수행됩니까 , deb아니면 소스 코드를 빌드하여 수행됩니까?msi

여기 몇 가지 예가 있어요.

  • Ubuntu에서 프로세스가 실행 파일을 실행하고 수동으로 다시 설치하여 소스 코드의 실행 파일을 덮어쓰면 configure프로세스 makemake install새 실행 파일이 아닌 원래 실행 파일을 계속해서 실행합니다.

  • msiWindwos 10에서는 프로세스가 실행 파일을 서비스로 실행할 때 설치 프로그램 파일을 통해 실행 파일을 다시 설치하면 서비스 프로세스가 다시 시작되어 새 실행 파일이 실행된다고 들었습니다 . Ubuntu 또는 Debian의 .deb 파일에서 설치할 때 동일하거나 유사한 상황이 있습니까?

감사해요.

답변1

커널과 실행 파일 유형에 따라 다릅니다. 실행 파일이 시작되거나 설치되는 방식에 의존하지 않습니다.

리눅스의 경우:

  • 기본 실행 파일(즉, 커널에서 직접 실행되는 기계어 코드가 포함된 이진 파일)의 경우 실행 파일을 런타임에 수정할 수 없습니다.

    $ cp /bin/sleep .
    $ ./sleep 999999 &
    $ echo >sleep
    sh: 1: cannot create sleep: Text file busy
    

    실행 파일을 삭제(즉, 링크 해제)하고 동일한 경로에 새 실행 파일을 생성할 수 있습니다. 파일이 아직 열려 있는 동안 삭제되는 다른 상황과 마찬가지로 실행 파일을 삭제해도 실행 중인 프로세스에 영향을 주지 않으며 파일이 더 이상 사용되지 않을 때까지, 즉 실행 중인 인스턴스 프로그램이 모두 종료될 때까지 디스크에서 실제로 파일이 제거되지 않습니다. .

  • 스크립트(로 시작 #!)의 경우 프로그램이 실행되는 동안 스크립트 파일을 수정할 수 있습니다. 이것이 프로그램에 영향을 미치는지 여부는 인터프리터가 스크립트를 읽는 방법에 따라 다릅니다. 실행을 시작하기 전에 전체 스크립트를 자체 메모리로 읽어들이면 실행에는 영향이 없습니다. 인터프리터가 요청 시 스크립트를 읽는 경우 실행에 영향을 미칠 수 있습니다 sh.

다른 많은 Unix 시스템에서는 이 동작을 공유하지만 전부는 아닙니다. IIRC 이전 버전의 Solaris에서는 기본 실행 파일의 수정이 허용되어 종종 충돌이 발생했습니다. 일부 Unix 변형(HP/UX 포함)은 현재 실행 중인 기본 실행 파일 삭제도 허용하지 않습니다.

대부분의 소프트웨어 설치 프로그램은 기존 바이너리를 덮어쓰는 대신 새 실행 파일을 설치하기 전에 기존 실행 파일을 제거합니다. 예를 들어

rm /bin/target
cp target /bin

그리고 단지 cp target /bin. 이것이 쉘 명령이 install수행하는 작업입니다. 그러나 /bin/target프로세스가 실행되는 동안 누군가 실행을 시도하면 프로그램이 손상되기 때문에 이는 이상적이지 않습니다 . cp파일을 임시 이름으로 복사한 다음 최종 이름으로 바꾸는 것이 가장 좋습니다. 파일 이름을 바꾸면(즉, 동일한 디렉터리로 이동하거나 더 일반적으로는 동일한 파일 시스템으로 이동) 이전 대상 파일이 있는 경우 삭제됩니다. dpkg예를 들어, 이것이 작동하는 방식입니다.

cp target /bin/target.tmp
mv /bin/target.tmp /bin/target

답변2

직접 시도해 볼 수 있습니다.

$ cp /usr/bin/sleep /tmp/sleep
$ /tmp/sleep 20 &
$ truncate -s 1 /tmp/sleep
truncate: cannot open '/tmp/sleep' for writing: Text file busy

시스템에서는 실행 중인 바이너리를 변경할 수 없습니다. 그러나 파일 링크를 해제하고 변경할 수 있습니다.

$ /tmp/sleep 20 &
$ rm /tmp/sleep
$ cp /usr/bin/ls /tmp/sleep
$ [2]-  Done                    /tmp/sleep 20

쉘 스크립트의 경우 사용 중인 바이너리가 /bin/bash이기 때문에 커널은 스크립트를 보호하지 않습니다. 쉘 스크립트 파일을 덮어쓰면 안 되지만 삭제하고 새 파일로 바꿀 수는 있습니다.

업데이트 패키지 설치는 패키저가 실행 중인 데몬 프로세스를 다시 시작하는지 여부에 따라 달라집니다. 규칙이 있는지는 모르겠지만 Fedora 시스템에서 일부 샘플 rpm 스크립트릿을 살펴본 결과 업데이트 시 다시 시작되는 것 같습니다. 예를 들어,

$ rpm --scripts -qf /usr/sbin/xinetd 
...
postuninstall scriptlet (using /bin/sh):
...
if [ $1 -ge 1 ] ; then 
    # Package upgrade, not uninstall 
    systemctl try-restart xinetd.service >/dev/null 2>&1 || : 
fi

rpm -U패키지를 업그레이드하면 새로운 사전 설치 및 사후 설치 스크립트릿이 실행되고 이전의 사전 제거 및 사후 설치 스크립트릿이 실행됩니다. 위에 표시된 것처럼 제거 후 systemd 서비스가 다시 시작됩니다.


댓글에서 이것도 확인해보세요답변공유 라이브러리에서 해석된 스크립트를 변경하는 방법은 인터프리터가 파일을 버퍼링하거나 다시 읽는 방법 또는 즉시 새 파일로 다시 컴파일하는 방법에 따라 크게 달라집니다.

답변3

실행 파일을 덮어쓰면 원본 실행 파일을 실행하는 프로세스에 영향이 있습니까?

일반적으로 아니요. 커널이 새 프로세스를 분기하고 실행할 때 실행 파일(프로그램 포함)이 읽혀지고 메모리에 로드된다는 것이 제가 이해한 것입니다.
기본 파일은 일반적으로 더 이상 필요하지 않습니다. 적어도 다음에 다른 프로세스에서 읽을 때까지는 필요하지 않습니다.
그렇기 때문에 시스템 프로그램이나 라이브러리를 대체하는 기본 파일을 업데이트한 후 컴퓨터를 다시 시작해야 합니다."실행중인 프로세스에 영향을 미칩니다"(즉, 교체)를 업데이트 파일에서 읽은 새 버전으로 바꿉니다.
새롭고 업데이트된 기능을 얻는 유일한 방법은 실행 중인 프로세스를 중지하고 새 파일에서 다시 로드하는 것입니다. 그러나 시스템 프로그램이나 커널 자체의 경우 브라우저에서처럼 프로그램을 닫을 수 없습니다. 따라서 새로운 업데이트 파일을 읽으려면 전체 시스템을 종료해야 합니다.

관련 정보