Ubuntu-OSX 호환성 및 사용 용이성 및 POSIX를 위해 #! / bin / sh 또는 #! / bin / bash를 사용하십시오.


18

원하는 셸을 호출하는 첫 번째 스크립트 줄로 사용할 수 있다는 것을 알고 있습니다.

시겠습니까 #!/bin/sh모든 유닉스 시스템과의 호환성이 절대 필요 조건 인 경우 추천?

내 경우에는 내가 관심있는 유일한 OS는 Ubuntu (Debian) 및 OSX입니다. #!/bin/bash그렇다면 두 시스템 모두에서 작동하고 사용할 수 있습니까?
또한 명령에 대해보다 현대적이고 명확한 구문으로 스크립트를보다 쉽게 ​​사용할 수 있습니까? 사용 #!/bin/sh은 POSIX 사용과 관련이 있습니까?


1
아마 가치가 많은 배포판 병합 시작했다고 지적 /bin하고 /usr/bin. 결과적으로 #!/usr/bin/env <shname>요즘 이식성 을 위해 사용 하는 것이 좋습니다 .
HalosGhost

답변:


15

우선 Bash가 사전 설치되어 있다고 가정 할 수 있다면 (내가 알고있는 모든 시스템의 경우) 다음 해시 뱅을 사용하여 호환 가능합니다.

#!/usr/bin/env bash

이것은 bash/bin있거나에 관계없이 구성되는 모든 것을 호출합니다 /usr/local/bin.

광범위한 시스템 (AIX, Solaris, 여러 BSD 버전 포함)의 대부분의 시스템 bash에서 서로 다른 위치에있게되고 env항상로 끝났습니다 /usr/bin/env. 그러나 속임수는 내 것이 아니라 Bash Cookbook의 저자가 작성한 것입니다.

어쨌든 그렇습니다. Bash를 사용하면 삶을 편하게 만드는 "현대"기능을 사용할 수 있습니다.

예를 들어 이중 괄호 :

[[ -f "/etc/debian_version" ]] && echo "This is a Debian flavor"

반면에 전통적인 쉘 방언에서는 다음을 사용해야합니다.

test -f "/etc/debian_version" && echo "This is a Debian flavor"

그러나 대괄호에 대한 가장 좋은 점은 정규식을 일치시킬 수 있다는 것입니다. 강타 해커 위키는 그 방향으로 당신에게 많은 유용한 정보를 제공 할 것입니다.

구문 $((2**10))에 따라 매우 편리한 표현식 이나 다른 산술 표현식을 사용할 수도 있습니다 $((expression)).

조금 구식이지만 서브 쉘에 백틱을 사용하는 것이 좋습니다. 그러나 $(command ...)다른 서브 쉘 레벨에서 많은 것을 피할 필요가 없기 때문에 호출 의 중첩 기능이 훨씬 편리합니다.

이것들은 Bash가 일반적인 일반적인 POSIX sh구문에 대해 제공하는 몇 가지 사항 입니다.

그러나 스크립트뿐만 아니라 셸에서 더 많은 전원을 원한다면을 살펴보십시오 zsh.


Bash는 매우 유용한 도구이지만 Bash 스크립팅 버그 (예 : access.redhat.com/security/cve/CVE-2014-6271)에 취약한 서비스를 시작하는 데 사용하지 않도록주의 하십시오 . 스틱 sh등의 작업을 위해.
Rick-777

1
Rick-777은 그 취약점이 크게 과장되었으며 내 의견으로는 귀하의 의견은 FUD라고 생각합니다. 시스템 서비스가 bash에서 실행되는 경우 해당 버그에 취약하지 않습니다. 원격 사용자가 FastCGI에서와 같이 하나 이상의 환경 변수에 직접 액세스하고 패치되지 않은 버전의 bash에서만 원격 액세스를 허용하면 bash 프로세스를 분기하면 버그에 취약합니다. 에 sh연결된 시스템 bash에서는을 사용하여 취약점을 완화하지 않습니다 sh.
Score_Undering

11

데비안과 우분투에서 /bin/sh이다 dash는 POSIX 호환 쉘이다. 을 지정 #!/bin/sh하면 스크립트에서 자신을 POSIX 문으로 제한해야합니다. 장점 dash은보다 빠르게 시작 bash하므로 스크립트가 더 짧은 시간 안에 작업을 수행 할 수 있다는 것입니다 .

많은 (대부분?) 다른 Linux 시스템에서 /bin/shis bash이므로 확장 #!/bin/sh을 사용하더라도 많은 스크립트가 shebang 라인으로 작성됩니다 bash.

bash확장 을 사용하려면 모든 시스템에서 가장 안전한 방법은 다음을 지정하는 것입니다 #!/bin/bash. 그렇게하면에 대한 의존성을 명시 적으로 나타 bash냅니다. 당신은 필요 데비안과 우분투에서이 작업을 수행 할 수 있습니다. 추가 보너스로 시작하면 /bin/sh bash일부 확장 기능이 비활성화됩니다 (자세한 내용은 bashPOSIX 모드 설명 참조). 따라서 #!/bin/bash를 최대한 활용하려면 지정 이 필요합니다 bash.

OS X /bin/bash에서도 사용할 수 있으며 /bin/sh입니다 bash. 지정 #!/bin/bash하면 잘 작동합니다.


5

예, OSX와 Linux는 모두 함께 제공됩니다 /bin/bash. 당신은 완벽하게 안전해야합니다. 그러나 이것은 POSIX 가 아닙니다 . POSIX 셸은 /bin/sh대부분의 시스템에 있으며 POSIX 호환을위한 가장 쉬운 방법이며 유일한 방법입니다.

많은 시스템 /bin/sh에서을 가리키고 bash다른 시스템에서는 다른 쉘을 가리킬 수 있습니다. dash예를 들어 데비안과 우분투에 대한 심볼릭 링크 입니다. 또한에 /bin/sh대한 링크 인 경우에도 bash쉘이 sh(from man bash, 강조 광산) 으로 호출되면 변경됩니다 .

bash가 sh라는 이름으로 호출되면 POSIX 표준도 준수하면서 sh의 히스토리 버전 시작 동작을 최대한 가깝게 모방하려고합니다. 대화식 로그인 쉘 또는 --login 옵션을 사용하는 비 대화식 쉘로 호출되면 먼저 / etc / profile 및 ~ / .profile의 명령을 순서대로 읽고 실행하려고 시도합니다. --noprofile 옵션을 사용하면이 동작을 막을 수 있습니다. 이름이 sh 인 대화식 쉘로 호출되면, bash는 변수 ENV를 찾고 값이 있으면 값을 확장합니다.
정의하고 확장 값을 읽고 실행할 파일 이름으로 사용합니다. sh로 호출 된 쉘은 다른 시작 파일에서 명령을 읽고 실행하려고 시도하지 않으므로 --rcfile 옵션은 적용되지 않습니다. sh라는 이름으로 호출 된 비 대화식 쉘은 다른 시작 파일을 읽으려고 시도하지 않습니다. sh로 호출하면 시작 파일을 읽은 후 bash가 posix 모드로 들어갑니다.


2

"모든 유닉스 시스템"과의 호환성이 절대적인 요구 사항 이고 그렇지 않은 경우 왜 쉘 스크립트를 작성 하는가? 그렇다면 #! /bin/shBash는 물론 어디에서나 설치가 보장되지 않으므로 반드시 사용해야합니다 /bin.

실제로 그것보다 훨씬 나쁩니다. 당신이 호환성을해야하는 경우 모든 유닉스 시스템, 즉, Solaris 및 AIX 같은 것들을 포함 자신의 쉘 환경을 동결 당신은 구식 같은 것들을 사용하는 것을 의미합니다 1995 년경 sort +N있음 - 구문 새로운 시스템이 떨어졌다를! 그리고 그것은 쉘 함수, 배열, 아니오 [[ ... ]], 아니오 ${foo#glob}, $(( ... ))산술, 아니오 $( ... )스타일 명령 대체, 큰 입력을 얻을 수있는 방법에 대한 작고 문서화되지 않은 상한을 의미 하지 않습니다 ...

당신은 아마와 귀찮게하지 멀리 얻을 수있는 많은 호환성하지만 처음에도 문제가 있다면, 나는 강하게 당신이 쉘보다 끔찍한 언어를 고려하는 것이 좋습니다. 기본 펄 인터프리터는 배쉬보다 사용할 수 있습니다 것.


감사. 원래 언급했듯이 "내 경우에는 내가 관심있는 유일한 OS는 Ubuntu (Debian) 및 OSX"입니다. 이것들은 지난 5 년 동안 내가 사용한 (그리고 많이 사용하는) 유일한 2 개의 시스템이므로 시스템에서만 작동하는 쉘 스크립트를 작성하는 이유입니다. 나는 보편적 인 스크립트와 그것이 제시 할 한계가 전혀 필요하지 않습니다.
Michael Durrant

@MichaelDurrant이 경우 쉘 스크립트를 작성할 필요가 없으며 그렇게해서는 안됩니다. 대신 완전한 이식성이 필요하지 않은 경우 옵션이되는 여러 가지 더 나은 스크립팅 언어를 사용해야합니다.
zwol
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.