![bash와 zsh가 [-1]을 1로 평가하는 이유는 무엇입니까?](https://rvso.com/image/1681636/bash%EC%99%80%20zsh%EA%B0%80%20%5B-1%5D%EC%9D%84%201%EB%A1%9C%20%ED%8F%89%EA%B0%80%ED%95%98%EB%8A%94%20%EC%9D%B4%EC%9C%A0%EB%8A%94%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
나는 이 놀라운 행동을 발견했으며 무슨 일이 일어나고 있는지 잘 이해할 수 없습니다.
$ bash -c 'echo [-1]'
1
$ zsh -c 'echo [-1]'
1
명령 구문 분석기가 표현식을 평가하려고 시도하는 것 같습니다.
$ echo [1,2,3]
1
$ echo [123-33]
1
표현식이 인용되거나 대괄호가 단지 대괄호임을 나타내면 이상한 평가가 생략되기 때문입니다.
$ echo \[123-33]
[123-33]
$ echo [123-33\]
[123-33]
$ echo '[123-33]'
[123-33]
단서를 찾다가 다음 인용문을 발견했습니다.
주의사항
Bash 연관 배열을 인덱싱할 때는 항상 따옴표를 사용하세요. 그렇지 않으면 정적 구문 분석기는 인덱스가 산술 표현식이라고 가정해야 합니다.
$ echo '${array[spaced string]}' | shfmt 1:16: not a valid arithmetic operator: string $ echo '${array[dash-string]}' | shfmt ${array[dash - string]}
컨텍스트에서 말할 배열이 없기 때문에 무엇을 만들어야 할지 잘 모르겠습니다.echo [1-1]
물론 이것은 내 환경의 문제로 인해 발생할 수 있지만 확인해 보면 다음과 같지 않은 것 같습니다.
$ env -i HOME=$(mktemp -d) bash --noprofile --norc
bash-5.1$ echo [1-1]
1
$ env -i HOME=$(mktemp -d) /bin/bash-4.4 --noprofile --norc
bash-4.4-4.4$ echo [1-1]
1
그러나 다시 우분투 상자에서는 다른 결과가 나타납니다.
$ bash --version | sed 1q; echo [1-1]
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
[1-1]
모든 옵션을 비활성화해도 이 동작은 변경되지 않습니다.
for i in `shopt | awk '/on$/ { print $1}'`; do shopt -u $i;done
이 대괄호 표현식이 평가되는 이유와 결과가 1인 이유를 알고 계십니까?
답변1
1
이는 현재 디렉터리에 파일 이름이 있는 경우에만 발생합니다 .
$ bash -c 'echo [-1]'
[-1]
$ touch 1
$ bash -c 'echo [-1]'
1
$ rm 1
$ bash -c 'echo [-1]'
[-1]
왜? 쉘은 또는 [-1]
이라는 파일과 일치하는 글로빙을 수행합니다 . 따라서 이러한 한 문자 이름을 가진 파일이 존재하면 glob이 일치하고 파일 이름을 얻습니다. 해당 파일이 없으면 glob은 변경되지 않은 상태로 유지됩니다.-
1
추신: 다음에서도 작동합니다 -
.
$ touch ./-
$ bash -c 'echo [-1]'
-