sh 또는 ash에 대한 bash 조건문을 다시 작성할 때 무엇을 확인해야 합니까?

sh 또는 ash에 대한 bash 조건문을 다시 작성할 때 무엇을 확인해야 합니까?

때로는 시스템에서 bash의 고급 기능을 사용할 수 없지만 sh 또는 ash보다 bash에서 조건을 생성하는 것이 더 쉽습니다. 조건이 일반적인 "예기치 않은 연산자"로 중단되지 않도록 다시 작성할 때 무엇을 확인해야 합니까? sh 또는 ash로 bash?

답변1

나는 표준 이나 명령 보다 ((...))and를 사용하여 조건문을 공식화하는 것이 더 쉽다 는 데 동의하지 않습니다 . 그리고 의 문제보다 훨씬 더 심각한 몇 가지 문제가 있습니다 .[[...]][test[[ ... ]](( ... ))[

[실패 하면예상치 못한 운영자오류입니다. 현재 사용하고 있지 않은 것 같습니다.껍데기명령 대신 올바르게(일반적으로 확장명을 인용하는 것을 잊어버립니다 [)

올바르고 휴대하기 좋게 사용하는 방법은 [/ test를 참고하시는 것이 가장 좋습니다.POSIX 사양.

안전을 보장하기 위한 몇 가지 기본 규칙은 다음과 같습니다.

  • 인수에서 모든 단어 확장( $var, , )을 인용합니다 $(cmd). $((arithmetic))이는 [.dash[[ ... ]](( ... ))

  • [및 이외의 인수를 4개 이상 전달하지 마세요 ]. 즉, 더 이상 사용되지 않는 -oand 연산자를 사용하지 말고 그룹화에 or를 -a사용하지 마십시오 . 따라서 일반적으로 표현은 다음과 같아야 합니다.()[

    • 의 단일 매개변수입니다 . 하지만 저는 null이 아닌지 확인하고 있음을 명시적으로 만드는 변형을 [ "$string" ]사용하는 것을 선호합니다 .[ -n "$string" ]$string
    • 단항 연산자( -f, -r, -n...) 및 해당 피연산자는 선택적으로 !부정을 위해 앞에 올 수 있습니다.
    • 이항 연산자( =, -gt...) 및 해당 피연산자 2개(앞에는 선택 사항)!
    • 산술 연산자의 피연산자는 선택적 부호가 있는 10진수 정수 상수여야 합니다. , 이러한 피연산자에서 선행 및 후행 공백을 허용하는 dash것과 같지만 모든 구현이 이를 수행하는 것은 아닙니다.bash[

휴대용 연산자 목록은 POSIX 표준을 확인하세요. dash표준에 대한 몇 가지 확장 도 있습니다( -nt, -ef, -k, -O, <, >² ...).

패턴 일치를 위해서는 대신 caseconstructor( )를 사용하세요 .case $var in ($pattern)...if [[ $var = $pattern ]]...

확장된 정규식 일치의 경우 다음을 사용할 수 있습니다 awk.

ere_match() { awk -- 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' "$1" "$2"; }
if ere_match "$string" "$regex"...

바꾸다:

if [[ $string =~ $regex ]]...

AND/OR의 경우 OR 셸 연산자(우선 순위가 동일함)를 사용하여 여러 [호출을 연결하고 명령 그룹을 사용하여 다른 명령(단지 .&&||[

if
  [ "$mode" = "$mode1" ] || {
    [ -f "$file" ] && [ -r "$file" ]
  }
then...

바꾸다:

if [[ $mode = "$mode1" || ( -f $file && -r $file ) ]]; then...

일부 bash's/ dash's/ zsh's/ ksh's/ yash's test/ 비 POSIX 연산자 [의 표준 동등물 :

  • -a file

답변2

스티븐 차제라스엄격하게 POSIX 호환 쉘과 다른 쉘 간의 구문 차이점과 기타 함정을 지적하는 좋은 답변이 있습니다. 이 답변은 다른 접근 방식을 취합니다.

bash인간으로서 , 또는 POSIX 이외의 확장이 포함된 다른 셸용으로 ksh작성된 스크립트를 POSIX 구문만 사용하는 스크립트로 안전하게 변환하는 것은 매우 어렵습니다 . 실수로 뭔가를 놓치기 쉬우며, 스크립트가 실패할 수도 있습니다. 아주 좋지 않은 시기에 말이죠.

제가 한동안 사용해 온 훌륭한 오픈 소스 도구가 있습니다.주택 검사. shellcheck의 역할은 쉘 스크립트에 대한 린터 역할을 하는 것입니다. 유사한 shebang을 지정 #!/usr/bin/env sh하거나 이 --shell sh옵션을 사용하면 shellcheck는 지정된 쉘에 유효하지 않은 구문을 자동으로 경고합니다.

Shellcheck에는 또한 오류 또는 경고의 의미에 대한 설명과 정확하고 안전한 코드에 대한 권장 사항과 함께 각 린팅 오류 또는 경고가 자체 페이지에 문서화되어 있는 아주 좋은 위키가 있습니다.

shellcheck를 설치하기로 선택한 경우 다음에서 최신 안정 버전을 설치하는 것이 좋습니다.GitHub의 릴리스 페이지내 경험에 따르면 패키지 관리자는 이전 버전의 shellcheck를 가지고 있기 때문에 패키지 관리자를 사용하는 대신.

답변3

피해야 할 가장 중요한 것은 이라고 말하고 싶습니다 [[ ... ]]. 둘 사이의 산술 (( ... ))도 아마도 작동하지 않을 것입니다.

변수가 설정되지 않은 경우 오류를 방지하려면 변수를 따옴표로 묶는 습관을 들이십시오 "$var".

-eq모든 산술 또는 논리 연산자는 or -a대신 =or 와 같이 대시가 있는 단어입니다 &&.

또한 사용shellcheck.net문법 검사에 사용됩니다. #!/bin/shBourne 쉘은 아니지만 POSIX 쉘을 사용하고 싶다고 shellcheck에 알리십시오. Bourne 쉘 스크립트를 테스트하는 방법도 있어야 합니다.

관련 정보