bash 쉘과 환경 변수를 배우고 있습니다.
echo a env를 테스트했습니다. var는 따옴표 없이 따옴표로 묶입니다(저는 이것을 터미널에 넣었습니다).
user@pc:~$ echo "$BASE_DEPENDENCIES"
build-essential \
cmake \
debhelper \
mesa-utils \
cppcheck \
xsltproc \
python-psutil \
python \
bc \
netcat-openbsd \
gnupg2 \
net-tools \
locales
user@pc:~$ echo $BASE_DEPENDENCIES
build-essential \ cmake \ debhelper \ mesa-utils \ cppcheck \ xsltproc \ python-psutil \ python \ bc \ netcat-openbsd \ gnupg2 \ net-tools \ locales
첫 번째 줄에는 새로운 줄과 공백이 있습니다. 두 번째에는 한 줄만 있습니다.
왜 이런 일이 발생합니까?
그건 그렇고, 내 시스템은 Ubuntu 17.04입니다.
답변1
하나 있다확장 순서bash가 입력 시 수행하는 작업:
확장 순서는 중괄호 확장, 인수 및 변수 확장, 산술 확장, 명령 대체(왼쪽에서 오른쪽으로 수행)입니다.
인용되지 않은 버전은 다음을 허용합니다.분사(내 강조점):
매개변수 확장, 명령 대체 및 산술 확장에 대한 쉘 스캔 결과큰따옴표 안에는 표시되지 않습니다.단어 분할에 사용됩니다.
...기본값은 입니다 . 이는 여러 단어가 된다는 $IFS
의미 입니다.build-essential \(newline)(other spaces)cmake ...
build-essential
\
cmake
- ...
...개행 문자와 각 공백 문자 내의 모든 문자를 효과적으로 제거합니다.
변수를 인용하면 무엇보다도 단어 분할이 방지됩니다.
추가 자료:
답변2
쉘은 1개 이상의 공백(즉, 공백, 탭, 개행) 문자를 사용하여 명령에서 인수를 구분합니다. 따옴표를 포함하지 않으면 값이 $BASE_DEPENDENCIES
N 인수로 확장됩니다. echo
모든 매개변수를 가져오고 단일 공백으로 구분된 각 매개변수를 인쇄하면 다음과 같은 결과를 얻을 수 있습니다.
build-essential<space>\<space>cmake<space>\...
따옴표는 공백 구분을 무시합니다. 따옴표 안의 모든 내용은 단일 인수로 전달됩니다. 이 경우 gets 값에는 $BASE_DEPENDENCIES
1개의 인수가 전달됩니다 echo
. echo
그런 다음 제공된 인수 중 하나를 인쇄합니다(공백, 개행 등은 그대로 유지).
더 잘 이해하려면 다음과 같은 간단한 셸 함수를 고려해 보세요. 이 경우 명령과 동일합니다.
foo() {
for i in "${@}"; do
echo "->'${i}'"
done
}
다음과 같은 변수가 있다고 가정해 보겠습니다.
x=" 1 2 3 4 "
따옴표가 없으면 4개의 매개변수를 얻습니다.
$ foo $x
->'1'
->'2'
->'3'
->'4'
따옴표를 사용하면 하나만 얻을 수 있습니다.
$ foo "$x"
->' 1 2 3 4 '
답변3
인용하면 공백이 보존되기 때문입니다. 이것을 다음과 비교해보세요:
# a=$(cal)
# echo $a
October 2017 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
# echo "$a"
October 2017
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
먼저 cal
명령 출력이 에 저장됩니다 a
. 그런 다음 따옴표 없이 따옴표와 함께 인쇄됩니다. 보시다시피 인용은 공백을 유지하지만 인용은 텍스트를 다음과 같이 구분하지 않습니다.토큰, 공백으로 구분됩니다.