[unix] shebang이 / bin / bash가 아닌 / bin / sh를 가리키는 이유가 있습니까?

내가 본 대부분의 쉘 스크립트 (내가 작성하지 않은 스크립트) 외에도 shebang이로 설정되어 있음을 알았습니다 #!/bin/sh. 이것은 오래된 스크립트에서 나를 놀라게하지는 않지만 상당히 새로운 스크립트에도 있습니다.

선호에 대한 이유가 /bin/sh이상은 /bin/bash이후 bash십 년에 걸쳐 다시 잘되어 가고 많은 리눅스와 BSD 시스템에서, 거의 편재, 종종 기본?



답변

  1. 기본적으로 bash를 제공하지 않는 시스템이 있습니다 (예 : FreeBSD).
  2. bash가 설치되어 있어도에 없을 수 있습니다 /bin.
  3. 대부분의 간단한 스크립트에는 bash가 필요하지 않습니다.
  4. POSIX 셸을 사용하면 이식성이 뛰어나고 스크립트는 다양한 시스템에서 실행됩니다.

답변

(데비안 관련 : Ubuntu, Mint 등) Linux의 대부분의 시스템 스크립트는 해당 시스템의 기본 / bin / sh 인 더 빠른 대시로 실행되도록 작성되었습니다. 그 이유는 두 가지입니다.

  • 시스템 속도. 더 작은 대시 코드는 더 빨리로드되고 더 빠르게 실행됩니다. 쉘 스크립트 프로그래머에게 약간의 추가 노력 (비용)이 필요하다.

  • 보안. 다양한 셸을 사용하면 버그에 대한 복원력이 향상됩니다. 데비안 시스템은 기본 쉘에 이러한 취약점이 없기 때문에 대부분 쉘 쇼크에 취약하지 않았습니다.

Bash는 실제로 사용자를 위한 기본 셸이며 , 더 강력하고 코딩을 쉽게하기 위해 훨씬 더 많은 요소를 가지고 있습니다. 또한 shMac OS (/ bin / sh에서 링크 된 것) 의 기본값 입니다. 그러나 bash링크 이름으로 호출 sh하면 posix 호환 쉘로 시작합니다.


답변

다른 사람들은 Bourne Again 쉘이 기본적이고 유비쿼터스라는 질문의 전제가 잘못되었다고 지적했다.

그 외에도 쉘 스크립트를 해석하기 위해 Bourne Again 쉘 이외의 다른 것을 사용하는 데는 정당한 이유가 있습니다. 이로 인해 수년 동안 우분투와 데비안의 큰 프로젝트가 bashism을 제거하고 시스템 초기화 ( System 5 의 많은 쉘 스크립트 rc) 및 패키지 설치 / 제거 사용 으로 많은 쉘 스크립트를 실행하도록 동기를 부여 했습니다. Bourne Again 쉘 대신 Debian Almquist 쉘.

간단히 말해 : Bourne Again 쉘은 대화식 기능으로 가득 차 있지만 POSIX 호환 쉘 스크립트를위한 가장 빠른 쉘 해석기는 아닙니다. 따라서 쉘 스크립트를 POSIX 호환으로 만들 수 있고 데비안 Almquist 쉘과 같은보다 가벼운 프로그램으로 해석하면 시스템 성능이 향상됩니다. (결국 데비안은 Almquist 쉘을 약간 조정하여 POSIX가 아닌 쉘 구조에 대한 지원을 추가했습니다.

그 결과 부트 스트랩 성능이 크게 향상되었습니다.

따라서 고려해야 할 두 가지 별개의 셸 클래스가 있습니다.

  • 계정 데이터베이스에서 사용자를위한 대화 형 로그인 셸로 구성된 화려한 대화 형 기능이 모두 포함 된 입니다.
  • 많은 스크립트를 빠르게 해석 하는 쉘로 쉘 스크립트 프로그램 에서 스크립트 인터프리터 로 사용됩니다 .

이것을 “선호 /bin/sh” 라고 말하는 것은 지나치게 간단합니다. 데비안은 실제로 최소한 두 가지 목표를 가지고있었습니다 .

  1. 데비안 Almquist 셸, Z 셸 (POSIX 모드), Bourne Again 셸 (POSIX 모드), MirBSD Korn 셸 등을 사용하는 관리자 /bin/sh는 다음 중 하나를 수행했습니다.

    1. … 스크립트를 가능한 한 이식성있게 만들어서 /bin/sh매핑 된 것을 전환 해도 문제가 발생하지 않습니다. 또는

    2. … 이식 불가능한 스크립트를 작성 하면 단순히 해당 맵을 예상하지 않고 올바른 운영체제 프로그램을 명시 적으로 대상 /bin/sh으로합니다.

  2. 데비안 Almquist가 기본 매핑을 쉘하고 있었다 /bin/sh대신 Bourne 쉘의 그 스크립트 너무 했다가 POSIX를 준수하는 (또는, 더 제대로, 데비안 정책 매뉴얼 준수)가 더 빨리 달렸다.

물론 일단 이것에 도달하면 훨씬 더 많은 것을 취할 수 있습니다. 등의 좋아하는의 효율성 장단점을 고려로 /bin/true/usr/bin/clear쉘 스크립트 또는 컴파일 된 프로그램 서비스를 제공합니다. 그러나 다행스럽게도이 답변의 범위를 벗어납니다. ☺

물론이 중 어느 것도 새로운 것이 아니며 유닉스 고유의 것도 아닙니다. 세기 초가되기 전에, 나는 “대화 형”과 “비대화 형”의 풍미가있는 명령 줄 인터프리터를 작성하고 출판했습니다.이 점은 doco의이 부분을 설명 COMSPEC하고 OS2_SHELL환경 변수 와 의 차이를 지적합니다 . 마찬가지로 데비안 System V에서 bashism 제거 rc와 패키지 설치 / 제거 스크립트에 대한 논의 는 1990 년대로 거슬러 올라갑니다.

추가 자료


답변

shebang이 / bin / bash가 아닌 / bin / sh를 가리키는 이유가 있습니까?

예. @Marco의 훌륭한 답변은 이것을 잘 설명합니다.

Shebang에서 무엇을 사용해야합니까?

자신의 스크립트를 작성할 때 shebang이 테스트 한 가장 일반적인 것을 가리켜 야합니다.

내 시스템 (Centos 6.6)에서 다음 sh과 연결되어 있습니다 bash.

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Dec  2  2014 /bin/sh -> bash

이것은 #!/bin/bash내가 스크립트에 바임이 없음을 확인하지 않는 한 항상 내 방에 사용한다는 것을 의미합니다 .

shebang을 설정하면 #!/bin/sh스크립트가의 모든 구현에서 작동 할 것을 약속합니다 sh.

이것은 스크립트가 bash와 함께 작동한다고 말하는 것보다 훨씬 더 큰 약속입니다.

다음은 sh시스템에서 사용중인 구현 에 따라 잘못 작동하는 스크립트의 예입니다 .

#!/bin/sh
n=1
a=$((++n))
echo $n

bash스크립트를 사용 하면 다음이 인쇄됩니다.

2

dash스크립트를 사용 하면 다음이 인쇄됩니다.

1

#!/bin/sh무엇 을 사용해야 합니까?

  • 스크립트를 확인하십시오 checkbashisms-모든 바임을 찾을 수는 없습니다. 위의 스크립트에서 bashism을 찾지 못했습니다.
  • 다른 sh구현을 사용하여 스크립트를 테스트하십시오 . 나는 일반적으로로 테스트 dash하지만 일부 bashism 또는 dashim이 여전히 빠져 나올 것으로 기대합니다.

우분투 위키 의 DashAsBinSh 페이지 에는 흥미로운 정보가 많이 있습니다.


답변

보다 강력하고 인체 공학적인 언어로 된 스크립트 대신 쉘 스크립트를 작성하는 유일한 이유 는 알 수없는 설치된 소프트웨어 세트가있는 레거시 시스템으로의 이식성이 다른 요소보다 더 중요하기 때문 입니다.

/bin/sh유닉스라고 부르는 모든 것에서 사용할 수있는 유일하고 유일한 스크립트 인터프리터입니다. 그러나 수많은 레거시 시스템 /bin/sh에서 관련 유틸리티는 POSIX.1-1996 “쉘 및 유틸리티”사양을 준수하지도 않으며, 더 현대적인 것은 아닙니다. 표준 호환 도구는 선택적인 추가 기능으로, /usr/xpg4그러한 분명하지 않은 위치에 설치됩니다. 1 이식 가능한 서브 세트 쉘 언어에 대한 스크립팅은 POSIX 쉘 언어에 대한 스크립팅보다 훨씬 지루하고 오류가 발생하기 쉽습니다. ( configure내가 믿지 않으면 언젠가 Autoconf 생성 스크립트를 읽으십시오 . 설정만으로 충분합니다.)

그러나 다른 스크립트 인터프리터 가 설치되어 있다고 가정 하면 (예 : Bash) 더 나은 스크립팅 언어를 위한 인터프리터 가 설치되어 있다고 가정 할 수 있습니다 . 펄은, 예를 들면, 배쉬 것보다 사용할 수 있습니다 것.

따라서 스크립트를 작성 해서는 안됩니다#! /bin/bash . 옵션 인 경우 더 나은 언어도 옵션입니다.

1 예를 들어, Solaris 10 및 이전 버전은 원본 Bourne 쉘을 로 배송 했습니다 /bin/sh. Solaris 11에서 ksh93으로 업데이트했다는 알림을 받았습니다.


답변

실제로 두 가지 중 하나를 사용해야합니다

#! /bin/env sh

또는

#! /bin/env bash

그렇게하면 해당 시스템에 설치되는 방식으로 쉘을 호출 할 수 있습니다.

매우 안전하려면 ( 예 : 단일 사용자 재부팅의 경우) sh그렇지 않으면를 사용하십시오 bash.


답변