왜 이런 일이 발생하는지 알려주세요.
Linux bash 셸에서:
ps
PID TTY TIME CMD
20406 pts/0 00:00:01 bash
26896 pts/0 00:00:00 ps
다음 명령을 실행합니다.
str="a b c d"
printf "%s\n" ` echo $str `
a
b
c
d
하지만 bash 스크립트에서
#!/bin/bash
.
.
.
.
str="a b c d"
printf "%s\n" ` echo $str `
다음과 같이 인쇄됩니다.
a b c d
그리고 스크립트의 예상 결과는 다음과 같아야 합니다.
a
b
c
d
내 Bash 스크립트에서 무엇을 놓치고 있나요? bash ENV나 이와 유사한 것일 수도 있습니다.
또한 shopt
bash 스크립트에서 명령을 실행했는데 결과는 다음과 같습니다.
utocd off
cdable_vars off
cdspell off
checkhash off
checkjobs off
checkwinsize off
cmdhist on
compat31 off
compat32 off
compat40 off
compat41 off
direxpand off
dirspell off
dotglob off
execfail off
expand_aliases off
extdebug off
extglob off
extquote on
failglob off
force_fignore on
globstar off
gnu_errfmt off
histappend off
histreedit off
histverify off
hostcomplete on
huponexit off
interactive_comments on
lastpipe off
lithist off
login_shell off
mailwarn off
no_empty_cmd_completion off
nocaseglob off
nocasematch off
nullglob off
progcomp on
promptvars on
restricted_shell off
shift_verbose off
sourcepath on
xpg_echo off
답변1
이 동작은 두 가지 상황에서만 재현할 수 있습니다.
큰따옴표 명령 대체:
#!/bin/bash str="a b c d" printf "%s\n" "`echo $str`"
또는 내부 필드 구분 기호(
IFS
변수)를 변경합니다. 예를 들면 다음과 같습니다.#!/bin/bash IFS=, str="a b c d" printf "%s\n" `echo $str`
두 경우 모두 출력은 다음과 같습니다.
$ ./test.sh
a b c d
첫 번째 경우를 수정하려면 따옴표를 제거하고 복원하려면 IFS
명령 대체 위의 기본값으로 설정하면 됩니다.
IFS=$' \t\n'
IFS
변경 후 출력이 달라지는 이유와 큰따옴표의 공통점이 무엇인지 조금 설명해주세요 .
끝부터 시작해 보겠습니다.
printf "%s\n" a b c d
와는 크게 다르다
printf "%s\n" 'a b c d'
첫 번째 경우에는 4개의 개별 단어가 있고 printf
이를 하나씩 출력하여 새 줄을 추가합니다. 두 번째 경우에는 전체 단어가 a b c d
단일 단어로 처리되어 printf
터미널에 직접 출력됩니다. 이제 큰따옴표를 추가하면 의 출력이 `echo $str`
단일 단어로 처리된다는 것이 분명해졌습니다.
이제 IFS
그것이 시작되는 곳입니다. 즉, 확장 후 단어를 분할하는 데 tt가 사용되므로 기본적으로 IFS=$' \t\n'
표현식은 echo a b c d
출력이지만 a b c d
명시 적인 따옴표를 사용하지 않아도 - 세계가 IFS=,
됩니다 . 'a b c d'
변수 없이 이를 더 명확하게 확인할 수 있습니다.
$ IFS=,
$ printf "%s\n" `echo a b c d`
a b c d
$ IFS=$' \t\n'
$ printf "%s\n" `echo a b c d`
a
b
c
d
$()
마지막 참고 사항: 백틱 대신 명령 대체 형식을 사용하는 것이 더 좋지만 이는 다른 주제입니다.