추가 읽기

추가 읽기

shoptZsh 에서 대신 사용하려고 할 때를 상기시키기 위해 setopt다음 별칭을 만들고 먼저 쉘 프롬프트에서 테스트했습니다.

$ alias shopt='echo "You\'re looking for setopt. This is Z shell, man, not Bash."'

외부 작은따옴표가 내부 큰따옴표와 일치하고 아포스트로피가 이스케이프되었지만 다음을 사용하여 닫는 따옴표를 완성하라는 메시지가 표시됩니다.

dquote > _

어떻게 되어가나요?

이스케이프가 무시되고 있거나 여러 레이어의 해석으로 인해 이중 이스케이프가 필요한 것 같습니다... 그래서 이 이론을 테스트하기 위해 다음까지 이중 이스케이프(및 삼중 이스케이프 등)를 시도했습니다.

alias shopt='echo "You\\\\\\\\\\\\\\\\\\\\\\'re looking for setopt. This is Z shell, man, not Bash." '

그리고안 돼요다른 동작을 확인하세요. 이것은 나에게 이해가 되지 않습니다. 어떤 종류의 이상한 마법이 쉘이 내가 예상한 대로 작동하지 못하게 막나요?

실제 해결책은 echo실제로는 아무 것도 필요하지 않기 때문에 따옴표를 사용하지 않고, 큰 따옴표를 사용 하고, 텍스트를 편집할 때 무시 alias되도록 아포스트로피를 이스케이프 처리하는 것입니다 . echo그럼 모두실제문제는 사라질 것입니다.

도와주세요? 이 혼란스러운 문제를 해결해야 합니다.

답변1

이건 zsh아니야fish.

에서는 zsh(및 에서 csh) 모든 Bourne과 같은 쉘에서와 같이작은따옴표는 이스케이프가 없는 강한 따옴표입니다.( rcquotes다음 옵션을 사용하지 않는 한@JdeBP 힌트따옴표 1) 을 zsh시뮬레이션합니다 rc. 작은따옴표로 묶인 문자열 안에는 작은따옴표를 사용할 수 없습니다. 먼저 작은따옴표로 묶인 문자열을 닫고 다른 인용 메커니즘(예: \또는 )을 사용하여 "리터럴 작은따옴표를 입력해야 합니다 .

alias shopt='echo "You'\''re looking for setopt. This is Z shell, man, not Bash."'

또는:

alias shopt='echo "You'"'"'re looking for setopt. This is Z shell, man, not Bash."'

다음과 같이 할 수도 있습니다.

alias shopt="echo \"You're looking for setopt. This is Z shell, man, not Bash.\""

( "..."약한\(여기서는 포함된 문자를 이스케이프하는 데 사용됨 ) 을 포함하여 따옴표 안의 여러 문자는 "여전히 특별합니다.

또는:

alias shopt=$'echo "You\'re looking for setopt. This is Z shell, man, not Bash."'

( 이스케이프할 수 있는 $'...'ksh93에 대한 또 다른 참조 )'\'

(BTW, in . set -o대신 표준을 사용할 수도 있습니다 . 역사적인 이유로 두 가지 옵션 세트가 있습니다. 하나는 설정용입니다 . 대부분의 다른 쉘과 마찬가지로 옵션 세트는 하나만 있습니다.setoptzshbashset -oshoptzsh


1 `rc`에서 Plan9 셸에는 Unix와 유사한 버전도 있습니다. [작은 따옴표가 유일한 인용 메커니즘입니다](/a/296147) (백슬래시와 큰 따옴표는 일반적인 문자입니다), 유일한 방법은 Enter literal Single입니다 따옴표의 경우 작은 따옴표 안에 "''"가 있으므로 "zsh -o rcquotes"를 사용하면 다음과 같이 할 수 있습니다.
alias shopt='echo "setopt를 찾고 계십니다. 이것은 Bash가 아닌 Z 쉘입니다."'

답변2

shopt='에코 "당신"

이것은 마법이 아닙니다. 이는 일반적인 POSIX 쉘 인용 작업입니다. 작은따옴표로 묶인 문자열에는 이스케이프 메커니즘이 없습니다.. 항상 다음 작은따옴표로 종료됩니다. 두 개의 연속된 작은따옴표 문자열 사이에 작은따옴표를 삽입하는 Z 셸 확장이 있습니다. 이를 사용할 수 있습니다. 또는 작은따옴표로 묶인 문자열을 종료하고 이스케이프된(또는 실제로는 작은따옴표가 아닌) 작은따옴표를 사용한 다음 두 번째 작은따옴표로 묶인 문자열을 시작할 수 있습니다.

또는 메시지에 약어를 사용할 수 없습니다. ☺

추가 읽기

답변3

다른 답변은 이러한 동작이 나타나는 이유를 아주 잘 설명합니다. 하지만 실제로 이 문제를 해결하는 방법에 대해 제안할 수 있다면 다음과 같습니다.

매우 복잡한 경우에도 별칭을 사용하지 마세요.

나는 당신을 믿습니다할 수 있는N 레벨의 따옴표를 중첩하는 방법을 알아내려고 노력하는 것은 골치 아픈 일이 될 수 있지만 앨리어싱을 위해 그럴만한 가치는 없습니다. 별칭이 너무 복잡해서 참조가 중요해지면 쉘 함수로 전환하세요.

shopt(){
    echo "You're looking for setopt. This is Z shell, man, not Bash."
}

이렇게 하면 전체 따옴표 레이어가 제거되고 나중에 쉘 함수에 더 많은 코드를 추가할 수 있으며 일반적으로 읽기가 더 쉽습니다. 또한 "줄의 시작 부분을 바꾸고 가능한 경우 나머지 단어를 배치하는" 별칭 접근 방식보다 인수가 삽입되는 방법과 위치를 더 세밀하게 제어할 수 있습니다. 예를 들어, (수정된) 별칭에 대해 다음을 입력하면:

shopt -s some_opt

...그러면 다음과 같은 출력이 표시됩니다.

You're looking for setopt. This is Z shell, man, not Bash. -s some_opt

이것은 당신이 원하는 것이 아닐 수도 있습니다. 쉘 함수는 전달된 모든 인수를 사용하고 자동으로 삭제합니다.

답변4

지금은 삭제된 댓글에서 답을 찾을 수 있는 힌트를 얻었습니다.

작은따옴표를 벗어날 수 없습니다.작은따옴표 문자열 안에.

최종 솔루션에서 큰따옴표로 묶인 문자열 내부의 작은따옴표를 확실히 이스케이프했기 때문에 큰따옴표로 묶인 문자열에는 이러한 제한이 존재하지 않습니다.

alias shopt="echo You\'re looking for setopt. This is Z shell, man, not Bash."

관련 정보