zsh에서 변수에 공백이 있는 스크립트를 호출하는 방법은 무엇입니까?

zsh에서 변수에 공백이 있는 스크립트를 호출하는 방법은 무엇입니까?

이것은 bash에서 예상대로 작동합니다.

> t="ls -l"
> $t #== ls -l
> "$t" #== "ls -l"
ls -l: command not found

하지만 zsh에서는 다음을 얻습니다.

> t="ls -l"
> $t #== "ls -l"
ls -l: command not found

쉘이 bash와 같이 변수 값을 다시 구문 분석하도록 하려면 어떻게 해야 합니까?

답변1

여러 인수로 확장되는 변수를 원하면 배열을 사용하십시오.

var=(ls -l)
$var

그러나 코드를 저장하는 데 가장 확실한 저장 유형은 함수입니다.

myfunction() ls -l

또는:

myfunction() ls -l "$@"

함수가 에 전달된 추가 인수를 허용하도록 합니다 ls.

bash대부분의 다른 Bourne 유사 쉘과 마찬가지로 인용되지 않은 변수가 확장 시 분할된다는 사실이 버그인 것 같습니다. 바라보다그것이 일으키는 문제의 유형. 하지만 이 동작을 원할 경우 이 shwordsplit옵션을 설정할 수 있습니다. globsubst복원을 위해 다른 옵션을 추가할 수도 있습니다.허점bash이는 변수 확장이 와일드카드(경로 이름 확장이라고도 함)의 영향을 받는 다른 Bourne 유사 쉘에서도 발견됩니다 . 또는 emulate sh전체 shebang을 수행하려면 또는 를 사용하세요 emulate ksh(그러나 더 많은 zsh 기능을 잃습니다).

거기로 갈 필요가 없습니다. zsh변수를 명시적으로 분할할 수도 있습니다.

var='ls -l'
$=var # split on $IFS like the $var of bash/sh
${(s[ ])var} # split on spaces only regardless of the value of $IFS
var='*.txt'
echo $~var # do pathname expansion like the $var of bash/sh
var='ls -ld -- *.txt'
$=~var # do both word splitting and filename generation

답변2

프로젝트 내용zsh 자주 묻는 질문.

간단히 말하면 긴 이야기입니다. 이 동작을 해결하는 방법에는 여러 가지가 있습니다.

  1. 놓다 setopt shwordsplit:
setopt shwordsplit
t="ls -l"
$t
  1. 사용 eval(가능한 보안 문제로 인해 피하는 것이 가장 좋음):
t="ls -l"
eval $t

답변3

변수가 이미 문자열로 정의된 경우 다음을 사용할 수 있습니다.

${=t}

=플래그는 변수를 확장할 때 토큰화를 사용하도록 zsh에 지시합니다.

관련 정보