이 스크립트는 왜 터미널에서 작동하지만 파일에서는 작동하지 않습니까?


19

이 셸 스크립트를 파일에 저장했습니다. 기본 문자열 대체를 수행합니다.

#!/bin/sh
html_file=$1
echo "html_file = $html_file"
substr=.pdf
pdf_file="${html_file/.html/.pdf}"
echo "pdf_file = $pdf_file"

명령 줄에 붙여 넣으면 정상적으로 작동합니다.

$ html_file="/home/max/for_pauld/test_no_base64.html"
  echo "html_file = $html_file"
  substr=.pdf
  pdf_file="${html_file/.html/.pdf}"
  echo "pdf_file = $pdf_file"

준다

html_file = /home/max/for_pauld/test_no_base64.html
pdf_file = /home/max/for_pauld/test_no_base64.pdf

그것이 위의 에코 출력 결과입니다. 의도 한대로 작동합니다.

하지만 스크립트를 호출하면

$ saucer "/home/max/for_pauld/test_no_base64.html"

나는이 출력을 얻는다 :

html_file = /home/max/for_pauld/test_no_base64.html
/home/max/bin/saucer: 5: /home/max/bin/saucer: Bad substitution

내 스크립트가 다른 버전의 bash 또는 다른 것을 사용하고 있습니까? Shebang 회선을 변경해야합니까?


6
그 매개 변수 확장은 bashism (잘, 비 POSIX)입니다 : shebang을 변경하십시오.
jasonwryan

감사! 효과가있었습니다. 나는 사이의 차이에 약간의 흐릿한라고 생각 sh하고 bash. 내가 읽어 줄게 귀하의 의견을 답변에 귀찮게 할 수 있다면 올바른 것으로 표시합니다.
Max Williams

자세한 답변을 위해 듀크에게 진드기를 주었지만 어쨌든 감사합니다.
Max Williams

2
@MaxWilliams : 간단히 말하면 sh는 원래 bourne shell입니다. 호환되는 모든 스크립트는 sh로 작성해야합니다. 그러나 많은 후속 쉘 (예 : bash, Bourne Again 쉘)은 "거의 호환 가능"하며 많은 추가 기능을 제공합니다. 당신이 사용한 대체품. 요즘에는 posix 기능 만 사용하는 것이 안전하지만 이식성은 더 좁은 세트 (즉, sh에만 해당)에 달려 있다는 점에 유의하십시오. 따라서 일반적으로 #!/usr/bin/env bashshebang으로 사용하고 원하는대로 위치 정의 된 대체물을 사용하지만 이식성 경고가 있습니다. 그리고 읽으십시오 : unix.stackexchange.com/a/48787/27616
Olivier Dulac

답변:


37

쉬 무엇입니까

sh(또는 Shell Command Language)는 POSIX 표준에 설명 된 프로그래밍 언어 입니다. 그것은 많은 구현이있다 ( ksh88, dash, ...). bash구현으로 간주 될 수도 있습니다 sh(아래 참조).

sh구현이 아닌 사양 이기 때문에 /bin/sh대부분의 POSIX 시스템에서 실제 구현에 대한 심볼릭 링크 (또는 하드 링크)입니다.

bash는 무엇입니까

bashshPOSIX 표준보다 몇 년 전부터 는 호환되는 구현 으로 시작 되었지만 시간이 지남에 따라 많은 확장 기능을 얻었습니다. 이러한 확장 중 많은 부분이 유효한 POSIX 셸 스크립트의 동작을 변경시킬 수 있습니다.bash 는 유효한 POSIX 쉘이 아닙니다. 오히려 POSIX 쉘 언어의 방언입니다.

bash--posixPOSIX 호환 스위치를 지원 합니다. 로 호출 된 경우 POSIX를 모방하려고 시도합니다 sh.

쉬 = 배쉬?

오랫동안 대부분의 GNU / Linux 시스템 /bin/sh을 가리 /bin/bash켰습니다. 결과적으로이 둘의 차이점을 무시하는 것이 거의 안전 해졌습니다. 그러나 최근에 바뀌기 시작했습니다.

시스템의 일부 인기있는 예는 어디 /bin/sh를 가리 키지 /bin/bash(어느 일부에 /bin/bash조차 존재하지 않을 수) 있습니다 :

  1. 심볼릭 링크 현대 데비안과 우분투 시스템 shdash기본적으로;
  2. Busybox 는 일반적으로 Linux 시스템 부팅 시간 동안 실행됩니다 initramfs. ash쉘 구현을 사용합니다 .
  3. BSD 및 일반적으로 비 Linux 시스템. OpenBSD는 pdkshKorn 쉘의 자손 인을 사용합니다. FreeBSD sh는 원래 UNIX Bourne 쉘의 자손입니다. Solaris는 sh오랫동안 POSIX를 준수하지 않는 자체 기능 을 가지고 있습니다 . Heirloom 프로젝트 에서 무료로 구현할 수 있습니다 .

/bin/sh시스템에서 어떤 점을 지적합니까?

합병증은 /bin/sh심볼릭 링크 또는 하드 링크 일 수 있다는 것입니다. 심볼릭 링크 인 경우 이식 가능한 해결 방법은 다음과 같습니다.

% file -h /bin/sh
/bin/sh: symbolic link to bash

하드 링크 인 경우 시도하십시오

% find -L /bin -samefile /bin/sh
/bin/sh
/bin/bash

실제로이 -L플래그는 심볼릭 링크와 하드 링크를 모두 포함하지만이 방법의 단점은 이식성이 없다는 점입니다 . 비록 GNU findFreeBSD find가 지원 하지만 POSIX 옵션 find을 지원할 필요가 없습니다 .-samefile

셰방 라인

«shebang»줄을 작성하여 어느 것을 사용할 것인지 결정하는 것은 전적으로 귀하의 몫입니다.

예 :

#!/bin/sh

사용하고 sh(그리고 그 일이 발생하면)

#!/bin/bash

사용 /bin/bash가능한 경우 사용 합니다 (사용할 수없는 경우 오류 메시지와 함께 실패). 물론 다른 구현을 지정할 수도 있습니다.

#!/bin/dash

사용할 것

내 스크립트의 sh경우 다음과 같은 이유로 선호 합니다.

  • 표준화되었다
  • 훨씬 간단하고 배우기 쉽다
  • POSIX 시스템 전체에 이식 가능 bash합니다.sh

사용 bash에도 이점이 있습니다. 이 기능은 다른 현대 프로그래밍 언어로 프로그래밍하는 것보다 프로그래밍이 더 편리하고 유사합니다. 여기에는 범위가 지정된 지역 변수 및 배열과 같은 것이 포함됩니다. 플레인 sh은 매우 최소한의 프로그래밍 언어입니다.


자세한 답변 주셔서 감사합니다 : 나는 데비안 기반이며 /bin/sh실제로에 대한 심볼릭 링크 인 Linux Mint를 사용 합니다 /bin/dash.
Max Williams

POSIX sh를 준수하려면 shebang을 완전히 제거하는 것이 가장 좋습니다. 쉘 명령 파일의 첫 번째 행이 "#!"문자로 시작하면 결과는 지정되지 않습니다. pubs.opengroup.org/onlinepubs/009695399/ 유틸리티 /…
Daniel Jour

4
@DanielJour 만약 유닉스 계열 시스템이 셰방에 대한 일반적인 지원을 중단했다면 실제로 사용할 수 없을 정도로 많은 것들이 망가질 것입니다. POSIX에 지정되어 있지 않더라도 사실상의 표준입니다. 실제 호환성 문제는 통역사의 경로가 다를 수 있다는 것입니다.
Barmar

23

@ Hunter.S.Thompson의 훌륭한 답변에 추가하면 스크립트의 이식 할 수없는 부분은

pdf_file="${html_file/.html/.pdf}"

${variable/search/replace}GNU 확장이다. 그러나 순수한 POSIX로 쉽게 피할 수 있습니다.

pdf_file="${html_file%.html}".pdf

헌터에 따르면, 이것은 shebang을 다음으로 변경하는 것보다 낫습니다. #! /bin/bash


고마워-나는 그것이 "순수한"수정이라는 데 동의하지만 bash는 터미널에서 기본적으로 사용하는 기본적으로 기본적으로 사용되는 것이기 때문에 shebang 이로 드 된 bash입니다. 명령 줄.
Max Williams

1
@MaxWilliams 물론 문제 없습니다. 이것은 주로 Q & A 데이터베이스에 대한 것입니다.
Philippos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.