Вы не видите точное содержание переменной, потому что вы просите bash изменить его. Самый основной эффект в этой команде:
$ echo hello # world
hello
$ echo "hello # world"
hello # world
Цитирование предотвращает скорлупу от интерпретации специального символа # в качестве стартового символа комментария, и, таким образом, он получает печать.
Пожалуйста read more here
Единственный правильный способ печати переменной точное содержание является процитировать его.
a='a \b
|c d'
Выше, var a получает точную строку, потому что она одинарная.
$ echo "$a"
a \b
|c d
выше значение вара a
точно воспроизведено из-за двойные кавычки.
Как только вы не процитировать расширение переменной $a
, вы получите что-то другое:
$ echo $a
a \b |c d
Это очень основное требование любой оболочки: квотирование.
И есть одинарные кавычки, двойные кавычки и цитаты с обратной косой чертой.
В вашем случае, чтобы воспроизвести то, что вы видите, вары на самом деле не равны, то они таковы:
$ c='bkup dt
'
$ c1='bkup dt'
То есть, с содержит дополнительный символ новой строки в конце по сравнению с c1 ,
Повторим ваши команды, но правильно цитируя, чтобы увидеть реальное содержимое каждого var (Пожалуйста, обратите внимание, что в пределах [[…]]
переменные могут использоваться в большинстве случаев без кавычек).
$ [[ $c1 == $c ]] || echo nope
nope
Переменные не равны.
$ [[ $c1 == "bkup dt" ]] || echo nope
переменная c1
точно равна bkup dt
(не выход).
$ [[ $c == "bkup dt" ]] || echo nope
nope
Нет, c
не совсем «bkup дт» (она имеет дополнительную новую строку).
$ hexdump -C <<<"$c"
00000000 62 6b 75 70 20 64 74 0a 0a |bkup dt..|
00000009
Обратите внимание на две новые строки в конце, теперь цитируемый переменная воспроизводит его внутреннее значение правильно с добавлением новой строки из <<<
.
Сравнить с $c1
.
$ hexdump -C <<<"$c1"
00000000 62 6b 75 70 20 64 74 0a |bkup dt.|
00000009
Только одна новая линия !!.
Может быть, лучший способ будет использовать:
$ printf '%s' "$c" | od -vAn -tx1c
62 6b 75 70 20 64 74 0a
b k u p d t \n
Здесь символ новой строки в переменной ясно показано.
Переменная $c1
не показывает, что:
$ printf '%s' "$c1" | od -vAn -tx1c
62 6b 75 70 20 64 74
b k u p d t
Команда DECLARE может быть использована также:
$ declare -p c
declare -- c="bkup dt
"
$ declare -p c1
declare -- c1="bkup dt"
Как кошки, СЭД и некоторые другие:
$ echo "$c" | cat -vET
bkup dt$
$
$ echo "$c1" | cat -vET
bkup dt$
$ echo "$c" | sed -n l
bkup dt$
$
$ echo "$c1" | sed -n l
bkup dt$
Если вы укажете расширение переменной и знаете, как выглядит новая строка.
В вашем втором примере также есть новая проблема с строкой.
$ cd /tmp; mkdir aaa; echo 2 > aaa/1; echo 2 > aaa/2
$ c=$(ls -A aaa)
$ echo $c | od -vAn -tx1c
31 20 32 0a
1 2 \n
В этом случае c
, кажется, есть пространство, но то, что он действительно является:
$ echo "$c" | od -vAn -tx1c
31 0a 32 0a
1 \n 2 \n
новой строки
Таким образом, эхо также выходит из строя (для пары недостающих котировок, оба они необходимы):
$ echo $(echo $c) | odc
31 20 32 0a
1 2 \n
$ echo "$(echo "$c")" | odc
31 0a 32 0a
1 \n 2 \n
Вы видите точное соответствие палатки переменной; вы просто получаете * дополнительную * новую строку ('0a'), вызванную этой строкой. 'printf '% s'" $ c "| hexdump -C' пропустит это, если вы не хотите просто игнорировать его. – chepner