스본과 길

스본과 길

Shebang에 경로가 필요한 이유는 무엇입니까?

잘못된

#!ruby

옳은

#!/usr/local/bin/ruby

#!/usr/bin/env ruby

운영 체제에는 등록된 명령의 경로에 대한 정보가 있어야 하는데 왜 여전히 해당 명령이 제공될 것으로 기대합니까?

답변1

아마도 커널을 더 단순하게 만들기 위한 것 같습니다. 커널이 실행 파일 경로를 검색하지 않는다고 생각합니다. 이는 C 라이브러리에서 처리됩니다. #!처리는 커널에서 수행되며 표준 C 라이브러리를 사용하지 않습니다.

또한 커널이 귀하의 경로가 무엇인지 알지 못한다고 생각합니다. $PATH환경변수이며 프로세스만이 환경을 갖는다. 커널은 그렇지 않습니다. 실행을 실행하는 프로세스의 환경에 액세스할 수 있다고 가정하지만 현재 커널에는 그러한 환경 변수에 액세스할 수 있는 것이 없다고 생각합니다.

답변2

PATH다음을 사용하여 검색 의미를 얻을 수 있습니다 env.

#!/usr/bin/env ruby  

당신이 원하는 의미가 있습니다

#!ruby

종속성이 PATH좋은 사례로 간주되지 않는 이유는 스크립트가 PATH 환경 변수의 내용에 대해 어떠한 가정도 할 수 없어 바이너리의 "순차 종속성 모델"이 깨졌기 때문입니다.

  1. /bin시작에 필요한 실행 파일이 포함되어 있습니다.
  2. /usr/bin운영 체제 설치에 사용되는 기타 실행 파일이 포함되어 있습니다.
  3. /usr/local/bin시스템 관리자가 설치하고 기본 운영 체제의 일부가 아닌 실행 파일이 포함되어 있습니다.
  4. ~/bin사용자 자신의 실행 파일을 포함합니다.

각 레벨은 시퀀스 후반부에 더 "적용"되는 바이너리가 있다고 가정해서는 안 되지만, 더 "기본적인" 이전 바이너리에 의존할 수 있습니다. PATH 변수는 종종 애플리케이션에서 기초로 이동하는데, 이는 위의 자연 종속 관계와 반대 방향입니다.

설명을 위해 Ruby의 스크립트가 ~/binRuby의 스크립트를 호출하면 어떻게 될까요? 스스로에게 물어보세요. /usr/local/bin스크립트는 설치된 운영 체제 버전에 따라 달라져야 합니까 /usr/bin/ruby, 아니면 사용자가 우연히 가지고 있는 개인 복사본에 따라 달라져야 합니까 ~/bin/ruby? PATH검색은 후자( ~/bin/ruby깨진 심볼릭 링크일 수 있음)와 관련된 예측할 수 없는 의미를 제공한 반면 경로를 베이킹하면 #!전자를 제공했습니다.

플랫폼 독립적인 다른 "운영 체제...등록된 명령의 경로에 대한 정보"는 실제로 없으므로 가장 쉬운 방법은 #!.

답변3

나는 이렇게 하면 귀하가 필요하거나 원할 경우 예비 통역사를 지정할 수 있다고 믿습니다. 예를 들어:

#!/home/user/myrubyinterpreter

쉘 스크립트에서 더 일반적입니다:

#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh

답변4

다른 이유도 있지만 보안 관점에서 볼 때 스크립트가 올바른 경로에 대해 가정하는 것을 결코 원하지 않습니다. 문제가 발생하여 잘못된 쉘이나 인터프리터가 실행되면 어떻게 되나요? 악의적인 사용자가 삽입한 것인가요? 아니면 특정 셸에 의존하고 잘못된 셸을 사용하면 충돌이 발생한다면 어떻게 될까요?

사용자는 자신의 경로를 엉망으로 만들고 물건을 깨뜨릴 수 있습니다. 사용자를 믿지 마세요 :-) 저는 사용자가 자신의 경로에서 잘못된 일을 하는 것에 의존하여 여러 공격을 실행했습니다. 일반적으로 일을 잘못된 순서로 가져옵니다. 그래서 일반 스크립트를 뒤집을 수 있습니다. 전화.

예, 스크립트를 직접 작성했다면 자신의 경로를 정리했다고 올바르게 주장할 수 있지만 통역사는 그러한 결정을 내릴 수 없다는 것을 알고 있습니다.

관련 정보