명령 대체의 별칭은 어떻게 작동해야 합니까?

명령 대체의 별칭은 어떻게 작동해야 합니까?

다양한 쉘을 사용하여 여러 스크립트를 테스트했는데 결과가 다양했습니다.

# test 1
foo(){ echo $(al);}
alias al='echo 123'
foo

# test 2
alias al='echo 123'
foo(){ echo $(al);}
alias al='echo abc'
foo

# test 3
alias foo='echo $('
echo $(foo echo '123'))

# test 4
alias foo='echo $('
echo "$(foo echo '123'))"

# test 5
alias bar='echo 123)'
echo $(bar
bash 5.1.16 (--posix 사용) 곤산 2020.0.0 zsh 5.9 대시 0.5.12 야쉬 2.53
테스트 1 123 123 123 알: 찾을 수 없음 그런 명령은 없습니다al
테스트 2 알파벳 알파벳 알파벳 123 123
테스트 3 예상치 못한 마크) )사고 123 123 123
테스트 4 123 123 123 123 123
테스트 5 예기치 않은 파일 끝 (견줄 나위 없는 명령을 찾을 수 없습니다: barecho 123 123

따라서 기본적으로 bash와 ksh는 지연 별칭 대체를 수행하는 반면 dash와 yash는 열성 별칭 대체를 수행합니다. zsh의 동작은 설명하기가 약간 어렵습니다. 특히 command 를 찾으려고 시도하는 경우 5의 경우 더욱 그렇습니다 barecho.

테스트 4는 모든 쉘이 일치하는 유일한 경우입니다. 이것은 혼란스럽습니다. 왜냐하면POSIX 표준 2.2.3 큰따옴표설명하다:

"$("와 일치하는 ")" 사이에도 포함된 따옴표 붙은 문자열의 입력 문자는 큰 따옴표의 영향을 받지 않아야 하지만 대신 단어가 확장될 때 출력이 "$(...)"를 대체하는 명령을 정의해야 합니다. . 일치하는 ")"를 찾으려면 토큰 인식의 토큰화 규칙(별칭 대체의 별칭 대체 제외)을 반복적으로 적용해야 합니다.

표준에서는 큰따옴표 안의 명령 대체에서 일치하는 괄호를 찾으려고 할 때 쉘이 별칭 대체를 사용해서는 안 된다고 명시하고 있습니다. 그러나 모든 쉘은 큰따옴표 안에 별칭 대체를 사용하고 일부 쉘은 큰따옴표 없이는 사용하지 않습니다.

문제는 특정 상황에서 특정 껍질이 잘못된 것인지, 아니면 단지 다른 것인지입니다. 즉, 이 상황에서 올바른 행동이 무엇인지 알려주는 몇 가지 규칙이 있습니까?

관련 정보