Один из вариантов - посмотреть на символы, которые вы пытаетесь использовать, с помощью шестнадцатеричной программы просмотра или редактора. 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
приведенном выше примере, поэтому что-то заменило не-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 "$" attie $ echo "`whoami`" attie $ echo "$(whoami)" attie $ cat <<EOF > $ > EOF attie
Эти методы заменяют компоненты соответствующим текстом. Чтобы избежать этого, используйте один из следующих подходов. Обратите внимание на использование одинарных кавычек ( '
) и « heredoc в кавычках » ( "EOF"
).
$ echo '$' $ $ echo '`whoami`' `whoami` $ echo '$(whoami)' $(whoami) $ cat <<"EOF" > $ > EOF $