내가 다음을 수행한다고 가정해 보겠습니다.
IFS=,
x="hello,hi,world"
y=$x
y
string 이 있으므로 다음과 같이 대체됩니다 hello hi world
.y=$x
y="hello hi world"
이제 다음 스크립트가 있다고 가정해 보겠습니다.
IFS=,
x="hello,hi,world"
if [ $x = "hello hi world" ]
then
echo "equal"
fi
위 스크립트를 실행할 때 다음 오류가 발생합니다.
test.sh: line 3: [: too many arguments
나는 명령문이 실행될 때 대체되는 대신 대체되기 if [ $x = "hello hi world" ]
때문에 이 오류가 발생한다고 가정합니다.if [ hello hi world = "hello hi world" ]
if [ "hello hi world" = "hello hi world" ]
따라서 이는 변수가 $x
해당 컨텍스트에 따라 두 가지 다른 방식(큰따옴표가 있는 경우와 큰따옴표가 없는 경우)으로 확장된다는 의미입니다.
내가 맞나요?
답변1
y
끈이 있을 거예요hello hi world
아니 난 할 수 없어. 변수 할당의 확장은 단어 분할이나 파일 이름 글로빙의 영향을 받지 않습니다. (어떤 의미에서는 항상 큰따옴표로 묶인 것처럼 동작합니다.) 다음을 참조하세요.언제 큰따옴표가 필요합니까?
$ IFS=,
$ x="hello,hi,world"; y=$x
$ echo "$y"
hello,hi,world
if [ $x = "hello hi world" ]
명령문이 다음으로 대체되었기 때문에 이 오류가 발생한다고 가정합니다.if [ hello hi world = "hello hi world" ]
네, 그렇죠. 텍스트 기반 대체는 아니지만 $x
여기에서 참조되지 않았기 때문에 토큰화를 거치며 명령은 예상한 4개 대신 [
6개의 다른 인수( hello
, hi
, world
, =
및 ) hello hi world
를 확인합니다.]
답변2
할당에 변수를 사용하면 참조와 관련하여 다르게 동작합니다. 존재하다
y=$x
분사를 수행하지 않습니다. 즉, 다음과 같습니다.
y="$x"
그러나 일반적인 매개변수 확장에서는 다음과 같습니다.
if [ $x =
따옴표가 있든 없든 차이가 있습니다. 참고: 따옴표를 사용하면 $x
확장되지 "hello hi world"
않지만 "hello,hi,world"
.
답변3
변수 할당 중에는 토큰화가 발생하지 y
않으므로 hello,hi,world
. 그러나 단어 분리는 내부적으로 발생하며 []
, 설정한 이후에는 별도의 단어 IFS=,
로 확장됩니다 .hello
hi
world
문제는 [
특정 개수의 인수가 필요하다는 점인데, 토큰화로 인해 너무 많은 인수를 받았다고 알려줍니다. 태그를 지정했으므로 bash
고급 명령을 사용하여 [[ ]]
단어 분리를 비활성화하면 오류가 발생하지 않습니다.
실제로 쌍을 토큰화하려면 x
다음을 수행하면 됩니다 y="$(IFS=','; echo $x)"
. 이것은 hello hi world
에 단어로 할당됩니다 y
.
답변4
인용 문제가 있습니다:
변수 확장:
y는 hello hi world라는 문자열을 받게 됩니다.
아니요, 그렇지 않습니다. 하지만 메아리가 있어인용되지 않음다음과 같은 값을 인쇄합니다.
$ IFS=, $ x="hello,hi,world" $ y=$x $ echo $y hello hi world
예, IFS 문자(
,
)는 변수 확장을 구분하고 echo는 인수 사이에 공백을 넣습니다. 자세히 확인하세요.$ printf '<%s>\n' $y <hello> <hi> <world>
그러나 참조된 확장은 IFS 또는 분할에 의해 변경되지 않습니다.
$ echo "$y" hello,hi,world $ printf '<%s>\n' "$y" <hello,hi,world>
테스트 라인
[ $x = "hello hi world" ]
여기서도 동일한 참조 문제가 발생하며 변수가 확장됩니다.그리고말로. 라인은 다음과 같습니다:
[ hello hi world = "hello hi world" ]
세 개의 매개변수 "hello", "hi" 및 "world"는 올바른 테스트 구조로 구문 분석될 수 없습니다.
그러나 이는 다음을 수행합니다.
$ y=hello,=,world,-o,hello $ [ $y = "hello" ] && echo yes || echo no yes
실행되는 내용은 다음과 같습니다.
[ hello = world -o hello = "hello" ] && echo yes || echo no
인용하면 분할을 피할 수 있습니다.
$ y=hello,hi,world $ [ "$y" = "hello,hi,world" ] && echo yes || echo no yes
다음 구성을 사용하면
[[
분할을 피할 수도 있습니다 .$ y=hello,hi,world $ [[ $y == "hello,hi,world" ]] && echo yes || echo no yes
너의 문제:
내가 맞나요?
아니요, 변수는 매번 같은 방식으로 확장됩니다.
긴 이야기 짧게
확장 기능을 인용해 보세요.