Один из вариантов - посмотреть на символы, которые вы пытаетесь использовать, с помощью шестнадцатеричной программы просмотра или редактора. hexdump
- хороший вариант, если вы ограничены терминалом.
$ hexdump -Cv <<"EOF"
> [ -f /etc/openvpn/client.conf ] && echo true
> EOF
00000000 5b 20 2d 66 20 2f 65 74 63 2f 6f 70 65 6e 76 70 |[ -f /etc/openvp|
00000010 6e 2f 63 6c 69 65 6e 74 2e 63 6f 6e 66 20 5d 20 |n/client.conf ] |
00000020 26 26 20 65 63 68 6f 20 74 72 75 65 0a |&& echo true.|
0000002d
Здесь вы можете видеть, что space
, close-square-brace
, space
правильные - 0x20
, 0x5D
, 0x20
.
Эти значения представляют собой коды ASCII, отображаемые в шестнадцатеричном формате. Любое значение за пределами диапазона 0x20
- 0x7E
не является « печатаемым символом » в отношении ASCII и, скорее всего, не будет хорошо работать с интерфейсами командной строки.
Примечание. Я скопировал вашу первую « ломаную » строку для использования в примере с hexdump
, поэтому что-то заменило пространство not-an-ASCII пространством ASCII между вашим исходным источником и вашим заданным вопросом.
Чтобы повторить это, выполните следующие действия:
- Введите
hexdump -Cv <<"EOF"
и нажмите Enter
- Вставьте текст, который вы хотели бы использовать
- Введите
EOF
в отдельной строке и нажмите Enter
Терминалы и интерфейсы командной строки плохо обрабатывают специальные символы - как вы обнаружили. Если вы не очень осторожны с форматированием документов, у вас также будут проблемы с Microsoft Word (и другими), использующими " умные кавычки ", тире, список можно продолжить ...
Найдите разницу: (верхняя часть - « умные цитаты », нижняя - « прямые цитаты »)
$ hexdump -Cv <<"EOF"
> “quoted string”
> EOF
00000000 e2 80 9c 71 75 6f 74 65 64 20 73 74 72 69 6e 67 |...quoted string|
00000010 e2 80 9d 0a |....|
00000014
Здесь открытые кавычки - это не простые ASCII-кавычки ("
), а серии Unicode / UTF-8 - 0xE2
, 0x80
, 0x9C
или U+201C
- которые терминал не будет обрабатывать, как вы могли ожидать.
Предложение Киви о cat -A
также делает работу:
$ cat -A <<"EOF"
> “quoted string”
> EOF
M-bM-^@M-^\quoted stringM-bM-^@M-^]$
Примечание: при использовании echo "..." | hd
, у вас есть шанс, что bash заменит части строки, которую вы пытаетесь проверить. Это особенно важно при проверке компонентов скрипта.
Например попробуйте:
$ echo "${USER}"
attie
$ echo "`whoami`"
attie
$ echo "$(whoami)"
attie
$ cat <<EOF
> ${USER}
> EOF
attie
Эти методы заменяют компоненты соответствующим текстом. Чтобы избежать этого, используйте один из следующих подходов. Обратите внимание на использование одинарных кавычек ('
) и " heredoc в кавычках " ("EOF"
).
$ echo '${USER}'
${USER}
$ echo '`whoami`'
`whoami`
$ echo '$(whoami)'
$(whoami)
$ cat <<"EOF"
> ${USER}
> EOF
${USER}