programing

방금 변수를 할당했는데 echo $variable이 다른 것을 나타냅니다.

newstyles 2023. 4. 19. 22:35

방금 변수를 할당했는데 echo $variable이 다른 것을 나타냅니다.

의 사례가 .echo $var는 방금 할당된 값과 다른 값을 표시할 수 있습니다.이 문제는 할당된 값이 "이중 따옴표", "단일 따옴표" 또는 따옴표 없음에 관계없이 발생합니다.

셸에서 변수를 올바르게 설정하려면 어떻게 해야 합니까?

별자리

은 「출력이 있다」입니다./* Foobar is free software */이치

$ var="/* Foobar is free software */"
$ echo $var 
/bin /boot /dev /etc /home /initrd.img /lib /lib64 /media /mnt /opt /proc ...

대괄호

은 " " " 입니다.[a-z]하지만 가끔 나는 대신 편지 한 통을 받는다!

$ var=[a-z]
$ echo $var
c

회선 피드(신규 회선)

예상 값은 별도의 행 목록이지만, 대신 모든 값이 한 줄에 있습니다!

$ cat file
foo
bar
baz

$ var=$(cat file)
$ echo $var
foo bar baz

다중 공간

테이블 헤더가 신중하게 정렬되기를 기대했지만, 대신 여러 공간이 사라지거나 하나로 축소됩니다!

$ var="       title     |    count"
$ echo $var
title | count

탭 구분 값이 두 개여야 하는데 공백 구분 값이 두 개 표시됩니다.

$ var=$'key\tvalue'
$ echo $var
key value

위의 모든 경우 변수가 올바르게 설정되었지만 올바르게 읽히지 않았습니다!올바른 방법은 다음을 참조할 때 큰따옴표사용하는 것입니다.

echo "$var"

이것은 주어진 모든 예에서 기대치를 제공합니다.항상 변수 참조를 인용하십시오!


왜요?

변수를 따옴표로 묶지 않으면 다음과 같이 됩니다.

  1. 이 공백으로 여러 단어로 분할되는 필드 분할을 수행합니다(기본값).

    전::/* Foobar is free software */

    그 : :/*,Foobar,is,free,software,*/

  2. 다음 각 단어는 경로 이름 확장을 거칩니다. 여기서 패턴은 일치하는 파일로 확장됩니다.

    전::/*

    그 : :/bin,/boot,/dev,/etc,/home, ...

  3. 마지막으로, 모든 인수는 에코로 전달되며, 에코에서는 단일 공백으로 구분되어 입력되며,

    /bin /boot /dev /etc /home Foobar is free software Desktop/ Downloads/
    

    변수 값 대신 사용할 수 있습니다.

변수가 따옴표로 묶이면 다음과 같이 됩니다.

  1. 그 값으로 대체되다.
  2. 2단계는 없습니다.

따라서 단어 분할 및 경로 이름 확장이 특별히 필요하지 않는 한 모든 변수 참조를 따옴표로 묶어야 합니다.셸체크 등의 툴은 도움이 되며 위의 모든 케이스에서 누락된 견적에 대해 경고합니다.

왜 이런 일이 일어나는지 알고 싶으실 겁니다.다른 사람의 훌륭한 설명과 함께 Gilles Unix & Linux에서 작성한 "Why does my shell script on skeepace or 기타 특수문자의 초크" 참조:

ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ?"$foo"용문 없없 ?떻 떻? ???

$foo''는.foo 더 것을 합니다:" 을 사용하다

  • 먼저 변수 값을 취합니다.
  • 필드 분할: 이 값을 공백으로 구분된 필드 목록으로 처리하고 결과 목록을 작성합니다.를 들어,에 를음음음이 포함되어 foo * bar ​입니다.foo,*,bar
  • 파일 이름 생성: 각 필드를 글로벌, 즉 와일드카드 패턴으로 처리하고 이 패턴과 일치하는 파일 이름 목록으로 대체합니다.패턴이 어떤 파일과도 일치하지 않으면 수정되지 않은 상태로 유지됩니다.예에서는 ㄴㄴㄴㄴ, ㄴㄴㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ,foo디렉토리의 을 표시하고 으로 (</FONT CHANGE:></FONT CHANGE:></FONT CHANGE:></FONT CHANGEFONT CHANGE:>)를 선택합니다.bar 있는 는, 「 있다」라고 결과가 됩니다foo,*,bar.

결과는 문자열 목록입니다.셸 구문에는 리스트콘텍스트와 스트링 콘텍스트의 2가지 콘텍스트가 있습니다.필드 분할 및 파일 이름 생성은 목록 컨텍스트에서만 수행되지만 대부분의 경우 발생합니다.컨텍스트를 로 둘러싸인 은 모두 분할되지 않습니다).큰따옴표로 둘러싸인 문자열 전체가 분할되지 않는 단일 문자열입니다(예외:"$@"( 위치 매개 변수 목록)으로합니다."$@" "$1" "$2" "$3"세 가지 위치 매개변수가 있는 경우.$*와 $@차이점을 참조하십시오.

입니다.$(foo) ★★★★★★★★★★★★★★★★★★★★★★. `foo` 참고로, ㅇㅇㅇㅇㅇ, ㅇㅇㅇㅇㅇㅇ는 하지 마세요`foo` 않습니다. 최신 항목을 지원합니다.$(foo)직관적인 인용 규칙이 있다는 점만 빼면 완전히 동일합니다.

, 되지 .IFS 또는 "Digits"가 되지 않습니다.-를 참조해 주세요.

이중 인용이 필요한 경우를 참조하십시오.견적을 생략할 수 있는 경우의 자세한 것은, 을 참조해 주세요.

이 모든 rigmarole이 발생하는 경우를 제외하고 변수와 명령어 치환 주위에 항상 큰따옴표를 사용해야 합니다.주의하세요.견적을 생략하면 오류뿐만 아니라 보안상의 취약점이 발생할 수 있습니다.

하는 기타 에,-n ★★★★★★★★★★★★★★★★★」-e할 수 echo의 POSIX (POSIX 의 경우, echo 몇 하여 "", "", ""를 소비합니다.-e(서양속담, 친구속담)

이를 방지하려면 세부 정보가 중요한 경우 대신사용하십시오.

다음과 같이 됩니다.

$ vars="-e -n -a"
$ echo $vars      # breaks because -e and -n can be treated as arguments to echo
-a
$ echo "$vars"
-e -n -a

해서 꼭 이 되는 것은 echo:

$ vars="-n"
$ echo "$vars"
$ ## not even an empty line was printed

...로 당신을 구할 수 있습니다.printf:

$ vars="-n"
$ printf '%s\n' "$vars"
-n

정확한 값을 얻으려면 사용자 큰따옴표를 사용합니다.다음과 같습니다.

echo "${var}"

그러면 당신의 가치를 정확하게 읽을 수 있습니다.

echo $var은 의 값에 IFS으로 탭 및 문자를 포함합니다기본적으로 공백, 탭 및 줄바꿈 문자가 포함됩니다.

[ks@localhost ~]$ echo -n "$IFS" | cat -vte
 ^I$

, 분할 분할할 때 를 단어합니다. 변수를 하는 ( 「」, 「」, 「」, 「」 。$var이치노

하는 것 에) 분할을 한 가지 은 (큰따옴표를 사용하는 것 외에) 을 설정하는 입니다.IFS무효로 합니다.http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_05 를 참조해 주세요.

IFS 값이 null일 경우 필드 분할은 수행되지 않습니다.

null로 설정하면 빈 값으로 설정됩니다.

IFS=

테스트:

[ks@localhost ~]$ echo -n "$IFS" | cat -vte
 ^I$
[ks@localhost ~]$ var=$'key\nvalue'
[ks@localhost ~]$ echo $var
key value
[ks@localhost ~]$ IFS=
[ks@localhost ~]$ echo $var
key
value
[ks@localhost ~]$ 

ks1322의 답변은 사용 중 문제를 식별하는 데 도움이 되었습니다.docker-compose exec:

[ ]를 -T "flag",docker-compose exec 중단 특수 문자가 나타납니다.b1b:

$ test=$(/usr/local/bin/docker-compose exec db bash -c "echo 1")
$ echo "${test}b"
b
echo "${test}" | cat -vte
1^M$

★★★★★★★★★★★★★★★★ -T "flag",docker-compose exec정상적으로 동작합니다.

$ test=$(/usr/local/bin/docker-compose exec -T db bash -c "echo 1")
$ echo "${test}b"
1b

따옴표로 만 아니라 변수 도 따옴표로 할 수 .tr공간을 새 선으로 변환합니다.

$ echo $var | tr " " "\n"
foo
bar
baz

이것은 조금 복잡하지만 배열 변수 사이의 구분자로 임의의 문자를 대체할 수 있기 때문에 출력에 다양성을 더합니다.

언급URL : https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else