언제 #! / bin / bash를 사용해야하고 언제 #! / bin / sh를 사용해야합니까?


104

쉘 스크립트 #!/bin/bash보다 언제 적절한가 #!/bin/sh?


55
당신이 사용하는 경우 bash기능과 구문보다는 sh기능과 구문을.
Mokubai


3
그것이 누군가에게 도움이된다면, 나는 당신의 스크립트가 shebang을 가지고 있다면 -isms vim를 강조 할 것임을 알았습니다 . 나는 bash 기능이 필요하기에 머리카락이 충분할 때만 변경합니다 . bash#!/bin/shbash
SeldomNeedy

@SeldomNeedy 기본적으로 강조되는 사항 중 일부는 POSIX 셸에서 잘 작동합니다. $(...)특히 불쾌합니다. 또한, 그들 중 일부는 미묘하다 [ <(...)cmd >& file오류 강조, 예를 들어, 그들은 단지와 함께 또는없이, 그들이 무엇을 의미하는지에 대한 특별한 강조가없는하지 않는다 g:is_bash]
Random832

@ Random832 최근에 vim의 issue-tracker 에서이 주제와 관련된 활동이 있었던 것 같습니다 .
SeldomNeedy

답변:


150

한마디로 :

  • POSIX sh 사양 의 수퍼 셋을 구현하는 여러 쉘이 있습니다 . 다른 시스템에서는 /bin/shash, bash, dash, ksh, zsh 및 & c에 대한 링크 일 수 있습니다. (항상 csh 또는 피쉬는 항상 호환 가능합니다.)

  • sh기능에만 충실하기 #!/bin/sh만하면 어떤 쉘이든 상관없이 스크립트를 사용할 수 있고 아마도 사용해야 할 수도 있습니다 .

  • 당신이 bash는 특정 기능 (예 : 배열)를 사용하여 시작하는 경우, 특별히 떠들썩한 파티를 요청해야 - 경우에도 때문에 /bin/sh이미에 떠들썩한 파티를 호출 하여 시스템이 켜져 있지 수도 다른 사람의 시스템 및 스크립트가 실행되지 않습니다. (물론 zsh 및 ksh에도 동일하게 적용됩니다.) shellcheck 를 사용하여 bashism 을 식별 할 수 있습니다 .

  • 스크립트가 개인적 용도로만 사용 되더라도 /bin/sh업그레이드 중에 일부 OS가 변경 되는 것을 볼 수 있습니다. 예를 들어 데비안에서는 bash로 사용되었지만 나중에 매우 작은 대시로 대체되었습니다. bashism을 사용했지만 #!/bin/sh갑자기 파산 한 스크립트 .

하나:

  • 심지어 #!/bin/bash매우 정확하지 않습니다. 다른 시스템에서는 bash가 /usr/binor /usr/pkg/bin또는에 있을 수 있습니다 /usr/local/bin.

  • 보다 안정적인 옵션은 #!/usr/bin/env bash$ PATH를 사용하는입니다. ( env도구 자체도 엄격하게 보장되는 것은 아니지만 /usr/bin/env여전히 많은 시스템에서 작동합니다 /bin/bash.)


10
좋은 대답입니다. CW로 하시겠습니까?
Mokubai

3
bash를 실행하면 이 모드에서 bash 특정 기능을 사용할 수 있는지 확인하지 않고 기능 /bin/sh을 모방하려고 시도 sh합니다 ( man page 참조 ). env도구는 대부분의 배포판에서 찾아야 할 posix 도구 이지만 일부는 posix를 존중하지 않을 수도 있습니다.
Brice

8
아니, 사실 POSIX는 특별히 언급 이있는 것으로 간주 될 수 없다 /bin" 응용 프로그램이 쉘 표준 PATH는 SH / / 빈 / sh 또는는 / usr / 빈 중 하나 인 것으로 가정 할 수 없으므로주의해야하며, 결정되어야한다 getconf PATH에 의해 리턴 된 PATH를 조사하여 리턴 된 경로 이름이 쉘 기본 제공 "이 아닌 절대 경로 이름 "인지 확인합니다. 또한 볼 이 질문을 구체적으로하고, 이 대답 .
terdon

12
흠, 그래서 POSIX가 실제로 #!스크립트를 작동 시키는 이식 가능한 방법을 정의하지 않는다는 것을 의미 합니까?
grawity

4
POSIX sh는 Bourne 이 아닙니다. Bourne의 직계 자손보다 초기 ksh의 파생물입니다. 그들을 구별하는 것은 간단하다 echo foo ^ cat방출 foo ^ catPOSIX 쉬에, 오직 방출 foo(로 Bourne 씨에 ^거기에 파이프 문자입니다).
Charles Duffy

18

실제로 스크립트를 개발하고 디버깅하는 데 사용한 쉘에 해당하는 shebang을 사용하십시오. 즉, 로그인 쉘이 bash있고 터미널에서 스크립트를 실행 파일로 실행하는 경우을 사용하십시오 #!/bin/bash. 배열 (또는 bash알고있는 기능)을 사용하지 않았으므로 원하는 쉘을 안전하게 선택할 수 있다고 가정하지 마십시오 . echo적절한 테스트 없이는 찾을 수없는 쉘 ( , 함수, 루프, 이름 지정) 사이에는 미묘한 차이가 많이 있습니다.

이것을 고려하십시오 : 당신이 떠나고 #!/bin/bash사용자가 그것을 가지고 있지 않으면, 그들은 명확한 오류 메시지를 보게 될 것입니다.

Error: /bin/bash not found

대부분의 사용자는 적절한 패키지를 설치하여 1 분 이내에이 문제를 해결할 수 있습니다. 반면에 shebang을 교체하고 심볼릭 링크가있는 #!/bin/sh시스템에서 테스트 를 수행하면없는 사용자에게 문제가 생길 수 있습니다. 그들은 다음과 같은 암호 오류 메시지를 보게 될 것입니다./bin/sh/bin/bashbash

Error in script.sh line 123: error parsing token xyz

수정하는 데 몇 시간이 걸릴 수 있으며 어떤 셸을 사용해야했는지에 대한 실마리는 없습니다.

shebang에서 다른 쉘을 사용하려는 이유는 많지 않습니다. 사용하는 쉘이 널리 보급되지 않은 이유가 있습니다. 또 다른 하나는 sh일부 시스템에서 성능 이 크게 빨라지고 스크립트가 성능 병목 현상을 일으키는 것입니다. 이 경우 대상 쉘로 스크립트를 철저히 테스트 한 다음 shebang을 변경하십시오.


@Hastur 나는 당신의 의견을 얻지 못했습니다. shebang은 확실히 어떤 쉘이 스크립트를 실행하는데 사용 될지 정의 할 것입니다. 내 대답이 그렇지 않다고 생각하십니까?
Dmitry Grigoryev

1
잊어 버려. "왜 사용하고 싶은지" 부분을 ​​잘못 이해했습니다 ...
Hastur

6

당신은 항상 사용해야 #! /bin/sh합니다.

쉘 스크립트에서 bash (또는 zsh 또는 fish 또는 ...) 확장자를 사용해서는 안됩니다.

당신은 오직 작업 쉘 스크립트 작성해야 어떤 (쉘 자체와 함께 갈 모든 "유틸리티"프로그램을 포함) 쉘 언어의 구현을. 이 일을 수행 할 수 있습니다 아마 걸릴 POSIX.1-2001 ( 하지 쉘과 유틸리티가 어떤 능력이 있는지에 대한 권위로 -2008)를,하지만 당신은 (예를 들어 솔라리스 포트에 레거시 시스템에 스크립트를 하루 호출 할 수 있음을 인식 또는 AIX) 1992 년경에 쉘과 유틸리티가 동결되었습니다.

진심으로?!

예, 진심 으로요

쉘은 끔찍한 프로그래밍 언어입니다. 그것이 유일하게 할 일은 모든 유닉스 설치가 보장 /bin/sh하는 유일한 스크립트 인터프리터입니다 .

핵심은 Perl 5 인터프리터 ( /usr/bin/perl) 의 일부 반복이 무작위로 선택된 Unix 설치에서 사용 가능한 것 보다 더 가능성이 높다는 것 (/(usr|opt)(/(local|sfw|pkg)?)?/bin/bash입니다. 다른 훌륭한 스크립팅 언어 (Python, Ruby, node.js 등) — 쉘과 비교할 때 해당 범주에 PHP와 Tcl도 포함시킬 것입니다.

따라서 bash 스크립트를 작성하는 옵션이 있으면 대신 끔찍한 프로그래밍 언어를 사용하는 옵션이 있습니다.

이제 간단한 쉘 스크립트, cron 작업이나 시퀀스에서 몇 개의 프로그램을 순서대로 실행하는 일종의 쉘 스크립트는 쉘 스크립트로 남겨 두는 데 아무런 문제가 없습니다. 그러나 간단한 쉘 스크립트에는 배열이나 함수가 필요하지 않습니다 [[. 그리고 다른 선택이 없을 때 복잡한 쉘 스크립트 만 작성해야합니다 . 예를 들어, autoconf 스크립트는 여전히 셸 스크립트입니다. 그러나 이러한 스크립트는 구성되는 프로그램과 관련된 모든 화신 에서 실행되어야 /bin/sh합니다. 즉, 확장을 사용할 수 없습니다. 당신은 아마 이러한 일 이전 독점 유닉스 걱정 할 필요는 없지만, 아마 해야 중 일부는 설치하지 마십시오, 현재 오픈 소스 BSD의 걱정bash기본적으로 최소한의 쉘만 제공하는 내장 환경 및 busybox.

결론적으로, 이식 가능한 쉘 언어로는 사용할 수없는 기능, 즉 스크립트가 쉘 스크립트를 유지하기에는 너무 복잡해 졌다는 신호를 원하는 순간 입니다. 더 나은 언어로 다시 작성하십시오.


4
죄송하지만 조금 어리 석습니다. 예, i) 분산되고 ii) 다른 환경에 배포 할 무언가를 작성하는 경우 basic을 고수해야합니다 sh. 그러나 다른 쉘을 사용 해서는 안된다는 과는 거리가 멀다 . 매일 수천 개의 (아마도 더 많은) 스크립트가 작성되며 대부분의 스크립트는 단일 머신에서만 실행됩니다. 조언은 프로덕션 코드에는 적합하지만 대부분의 스크립트가 작성되는 일상적인 "sysdaminy"작업에는 적합하지 않습니다. 내 스크립트가 나와 Linux 시스템에서만 사용된다는 것을 알고 있다면 bash는 괜찮습니다.
terdon

1
@terdon 요점은 bash 스크립트를 작성하는 옵션이 있다면 perl (또는 무엇이든) 스크립트를 작성하는 옵션도 있으며 이것이 항상 더 나은 선택이라는 것입니다.
zwol

@terdon 정답은 어리석은 것이 아니며, 귀하의 의견은 단순히 순진합니다. 쉘 스크립트는 Perl과 비교하여 디버깅하기가 끔찍합니다. 그래픽 디버깅과 모든 기능을 갖춘 완전한 IDE를 쉽게 사용할 수 있습니다. 또한, 작은 일을 위해 매일 쓰여지는 대부분의 스크립트는 다시 변경되거나 다시 변경되는 경향이 있으며, 자라며 동료 나 인터넷 등에 사례로 복사됩니다. 그러한 위험을 감수 할 이유가 없습니다.
Thorsten Schöning 님이

@ ThorstenSchöning 나는 조금 바보 말했다 . 이것이 유닉스와 리눅스 이거나 심지어 스택 오버플로 라면 동의 할 수도 있습니다. 우리가 일반적인 모범 사례 또는 전문 프로그래머에 대해 이야기하고 있다면 물론 기본 POSIX sh를 따르는 것이 가장 좋습니다. 그러나 이것은 최종 사용자를 목표로하고 쉘 스크립트를 작성할 때 bash 또는 zsh를 사용하지 말라고 알려주는 사이트 인 Super User 입니다.
terdon

@terdon 내 의견으로는, 최종 사용자가 복잡한 쉘 스크립트를 작성하지 못하게하는 것이 실제로 중요하다. 전문가들은 평균적으로 더 높은 기술 수준을 갖습니다 (따라서 복잡한 쉘 스크립팅의 함정에 대처할 수있는 가능성이 높음) 좌절에.
zwol

4

일반적으로 기능보다 시간이 더 중요한 경우 더 빠른 쉘을 사용합니다. sh는 종종 대시로 별칭이 지정되며 루트의 cron 작업 또는 모든 (nano) 초 단위로 계산되는 배치 작업에 사용되는 경향이 있습니다.


2
파일 시스템에서 추가 쉘 인터프리터를로드하면 이러한 이점을 무시할 수 있으며 실제 기계 사이클과 동일한 크기의 나노초가 C 및 어셈블리 언어 프로그래머의 도메인 인 모든 것이 중요합니다.
rackandboneman

나노초는 수십억 개가있는 크론 작업에만 차이가 있으며 크론은 그렇게 많은 것을 처리 할 수 ​​없습니다.
Dmitry Grigoryev

1
mckenzm이 약간 과장 되더라도 더 많은 성능을 갖는 것이 더 낫다는 것을 부정하지는 않습니다! "나노"부분에 매달리지 마십시오. (나노초는 실시간 시스템 등의 내부 루프가 아니라면 C로 계산되지 않습니다!)
jpaugh

1
@jpaugh 특정 작업이 적어도 특정 시간이 걸린다고 가정하는 (레거시) 시스템으로 작업하지 않는 한. 일어난다!
JAB

3

더 간단히 말해서, sh대부분의 시스템에서 이식성이 가장 중요하고 bashbash 버전이 지원하는 경우 배열과 같은 특정 기능을 사용하려는 경우 사용하십시오.


1
  • sh (대부분의 경우), 특별히 필요한 경우 bash (또는 ksh 또는 기타)

가장 안전한 길. 하드 코딩 된 경우 / usr / bin / 일 것입니다. shellOfChoice하지만 항상 PATH를 변경할 수있는 '기본 위치'로 변경하려는 새로운 규칙은 다음과 같습니다.

#! / usr / bin / env sh 또는
#! / usr / bin / env bash
또는 예를 들어 perl 스크립트
#! / usr / bin / env perl -w

물론, 스크립트가 자동으로 새로운 PATH를 사용하지 않을 이유가있는 경우 계속해서 하드 코딩해야합니다. 그러면 / usr / bin / something이 가장 많이 사용됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.