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


53

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

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


23
/bin/sh특정 bash기능을 사용하지 않는 경우 사용하는 것이 좋습니다 . 언젠가는 스크립트가 설치되어 있지 않은 시스템 (원격 서버, 내장 컴퓨터)에서 스크립트 중 하나를 사용해야 할 수 있습니다.
Mathieu

1
일반적으로 당신은 의견에 근거하여 스스로에게 답변을주는 질문을하지 말아야합니다 (이 질문에 대답 할 수 있다고 생각할 수있는 유일한 방법입니다 – 그러나 그것은 단지 제 의견입니다 ) .
mikeserv

9
여러 해에 걸쳐이 문제를 해결 한 2 개 이상의 조직을 지적하고 역사와 결과를 살펴보면 단순한 의견 없이도이 질문에 대답 할 수 있다고 생각합니다. 더 많은 독서가 첨부되어 부팅합니다. ☺
JdeBP

3
@JulesMazur ...the answers so far are fairly subjective..."주관적인"진술은 본질적으로 정의에 의한 의견에 근거합니다. /bin/bashbash가 명시 적으로 필요한 경우에만 사용해야합니다. 오래 전부터 개발자로서 40 년 이상 동안 테스트 할 때를 제외하고 bash명시 적으로 필요 하지 않았습니다 . (또한 쉘 확장을 피하려고 노력하지만 대부분의 스크립트는 배포 용입니다.) 그물에있는 많은 스크립트도 광범위하게 사용해야합니다.
user2338816

2
@ user2338816 나의 나쁜, 나는 objective를 의미했다 . 포인트 주셔서 감사합니다!
Jules

답변:


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

17
또 다른 이유 : 종종 / bin / sh가 bash보다 빠르거나 최소한 더 빨리로드됩니다 (작은 크기로 인해).
derobert

5
@derobert, /bin/sh그렇지 않은 경우 빠른 bash여전히 OS / X 또는 RHEL과 같은 몇 가지 시스템이있다, /bin/sh있다가 bash.
Stéphane Chazelas

1
bash는 이전 버전과 호환되기 때문에 일부 OS는 링크합니다.
Sobrique

7
꽤 많은 스크립트는 가정 /bin/sh이다 /bin/bash. 우분투는 bash 에서 dash로 전환하면 모두 깨졌습니다.
atamanroman

19
@atamanroman : 처음에는 스크립트가 잘못되었습니다. #!/bin/bashBash를 원한다면 사용 했을 것입니다. 변경은 대부분 데비안에서 업스트림에 이루어졌습니다. 사용자 경험을 향상 시켰으며 시스템 시작 시간에 상당한 영향을 미쳤습니다. 보안에도 긍정적 인 영향을 미쳤습니다. "Shellshock"을 참조하십시오.
Dietrich Epp

28

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

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

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

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


2
더 간단한 쉘의 사용 가능한 도구 세트가 제한되어 있으므로 코드 작성이 더 어려워집니다 (이에 대한 광란의 전쟁을 피하십시오). 그래서 zsh와 같은 일부 사용자는 bash보다 더 많은 도구를 사용할 수 있습니다. 나는 두 극단 사이의 균형이므로 Bash를 더 좋아합니다.

4
@RobertL은 ksh에 추가되고 bash가 채택한 많은 기능이 강력하고 정확한 스크립트 작성 프로세스를 실질적으로 용이하게하기 때문에 존재합니다. 예를 들어 간접 할당 및 평가를 안전하게 수행 할 수있는 다양한 추가 기능이 없으면 eval보안 담당자가 노출 된 상태에서를 사용하여 자신을 찾을 수 있습니다 . 마찬가지로 내장 정규식 지원이 없으면 한 줄 내에서도 일치시키기 위해 외부 명령을 사용해야 할 수 있습니다.
Charles Duffy

1
@RuiFRibeiro, 데비안에서는 정적으로 링크 된 것이 없습니다 . 대시는 더 제한적이지만 주로 대화 형 기능 (완료 등)으로 제한되므로 스크립트 속도가 더 빠릅니다.
Jan Hudec

21

다른 사람들은 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 년대로 거슬러 올라갑니다.

추가 자료


2
"결국 데비안은 Almquist 쉘을 약간 조정하여 POSIX 이외의 쉘 구조에 대한 지원을 추가해야했습니다. —이 링크에 대한 정보가있는 많은 링크는 무엇입니까? 매우 흥미로운 것 같습니다. :)
와일드 카드

3
IMHO, 성과는 사람들이 변화에 동의하도록 동기를 부여 할뿐입니다. 변경의 초기 큰 이유는 bash가 이전 버전과의 호환성을 계속 유지했기 때문입니다. 스크립트는 한 버전의 bash에서 작동하지만 다른 버전에서는 실패했기 때문에 개인적으로 bash 문제를 적어도 3 번 수정해야했습니다 (일반적으로 OS 업그레이드 후 발생). 대시는 단지 약간 빠른 통역사가 아닙니다. 또한 행동 측면에서 훨씬 안정적입니다.
slebetman

Schily Bourne Shellman 페이지 의 주석은 schilytools.sourceforge.net/bosh.html 이 사람들이 휴대용 스크립트를 작성하는 방법을 이해할 수 있도록 해주는 지 ( Bourne Shell features1989 년 에만 의존 )에 관심이있을 것입니다. 내가 한 것은 오래된 Bourne Shells에 없었던 모든 개선 사항을 언급하는 것이 었습니다. BTW : 나는 또한 bashism 목록을 대시로 알고 싶다.
schily

8

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 페이지 에는 흥미로운 정보가 많이 있습니다.


6
"자신의 스크립트를 작성할 때 shebang을 테스트 한 가장 일반적인 사항을 가리켜 야합니다 .... shebang을 #! / bin / sh로 설정하면 스크립트가 sh의 모든 구현에서 작동 할 것이라고 약속합니다. " 훌륭한 지적입니다. +1, 당신은 내가 미래를 위해 어떻게 내 세방을 쓰는지 다시 생각하게 만들었습니다. 감사합니다! :)
와일드 카드

2
글쎄, 모든 구현이 아니다 /bin/sh; POSIX 호환 제품 만.
Blacklight Shining

4

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

/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으로 업데이트했다는 알림을 받았습니다.


3
시스템을 부팅하기위한 스크립트를 어떤 언어로 작성 하시겠습니까? 아니면 SOHO 라우터 내부 (제한된 임베디드 시스템)? 아니면 안드로이드? 모든 경우에 쉘을 사용할 수 있습니다. 펄 아니야

1
답변의 Solaris 관련 부분에 약간의 정확성이 있습니다. 솔라리스 10 세 이상에서 /bin/sh입니다 하지 POSIX.1-1996 실제로 사전 POSIX 구문 원래 Bourne 쉘. 즉 만드는 #!/bin/sh스크립트가이 버전으로 실행하기 위해 매우 가난한 오두막을. Solaris의 이식 가능한 스크립트는 #!/usr/xpg4/bin/sh다른 OS에서는 이식성이 떨어집니다. 최신 Solaris에서 2011 년에 처음 릴리스 된 Oracle Solaris 11 /bin/shksh93최신 POSIX 사양을 준수하며 최신 확장 기능을 갖춘 최신 버전입니다.
jlliagre

1
@BinaryZebra : "쉘"을 사용할 수 있습니다. 그러나 bash는 반드시 쉘 (특히 ashbusybox와 함께 제공되는 대부분의 SOHO 라우터 사용 )은 아니며 zwol이 perl이 bash보다 더 일반적으로 사용 가능하다고 생각하는 경향이 있습니다.
Ben Voigt

1
@BenVoigt이 문장 "쉘 스크립트를 작성하는 유일한 이유"에 대해 언급하고 있습니다. 일부 작업에 쉘이 필요한 일부 인스턴스가 여전히 있습니다 (모두는 아님). 그것들은 내 머리 꼭대기에서 몇 가지 예입니다. OTOH 메모리가 충분하고 (오늘날 거의 모든 표준에서) Perl (또는 Python 또는 ....)을 충분히 설치하는 시스템은 매우 빠르고 쉽습니다. 그러나 특정 쉘을 옹호하지는 않습니다. 내 의견에서 어디서 읽습니까?

2
" bash사용 가능한 경우 더 나은 언어이므로 bash코드를 작성해서는 안된다 " 는 귀하의 의견이 많고 비 사실적 주장에 완전히 동의하지 않습니다 . 또한 @sixtyfootersdude가 지적했듯이 스크립트가 POSIX 셸에서 작동하는지 테스트 하지 않는 한 항상 사용해야 합니다. #!/bin/bash
와일드 카드

0

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

#! /bin/env sh

또는

#! /bin/env bash

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

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


6
에서 이 답변 : the advantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH. The disadvantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH.이것은 아마도 적용 sh하고 bash.
Jules

12
아니요, #!/bin/env이식 가능한 스크립트에는 아무 것도 사용해서는 안됩니다 . /bin/sh존재하고 작동하는 POSIX 호환 쉘 이라고 가정하는 것이 합리적 입니다. 반면에 내 시스템 중 어느 것도 /bin/env.
Blacklight Shining

또한 좋은 지적입니다.
Jules

1
@Blacklight Shining에서 POSIX 호환 쉘을 가정하는 것은 확실히 잘못되었습니다 /bin/sh. POSIX는이를 요구하지 않으며 POSIX 인증 플랫폼에서 POSIX 호환 환경을 얻기 위해 다른 규칙을 정의합니다.
schily

4
/usr/bin/env보편적으로 사용할 수 없습니다 ...
vonbrand
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.