Да,
nl='
'
case $var in
(*"$nl"*) echo yes;;
(*) echo no;;
esac
(В принципе, мне нравится case
заключать в кавычки все расширения переменных внутри шаблона, если я не хочу, чтобы они рассматривались как шаблон, хотя здесь это не имеет значения, поскольку $nl
не содержит подстановочных знаков).
или
case $var in
(*'
'*) echo yes;;
(*) echo no;;
esac
Должно ли все работать и быть POSIX-совместимым, и что я буду использовать для этого. Если вы удалите (
s, он будет работать даже в старой оболочке Bourne.
Для другого способа установить $nl
переменную:
eval "$(printf 'nl="\n"')"
Обратите внимание, что $'\n'
планируется включить в следующую версию стандарта POSIX . Это уже поддерживается ksh93
, zsh
, bash
, mksh
, BusyBox и FreeBSD , по sh
крайней мере (по состоянию на февраль 2018 года).
Что касается того, достаточно ли у вас теста, у вас есть тест для обоих случаев, поэтому будет тестировать все пути кода.
В настоящее время есть кое-что, что не определено явно в спецификации POSIX: соответствует ли *
строка, содержащая последовательности байтов, которые не образуют допустимые символы, или переменные оболочки могут содержать эти строки.
На практике, кроме тех, yash
чьи переменные могут содержать только символы, и кроме байтов NUL (которые никакая оболочка не zsh
может хранить в своих переменных), они *$nl*
должны совпадать с любой строкой, которая содержит, $nl
даже если они содержат последовательности байтов, которые не формируют действительные символы (как $'\x80'
в UTF-8).
find
Например, некоторые реализации не будут соответствовать -name "*$nl*"
на них, поэтому, если вы тестируете новую оболочку, и если вы намереваетесь иметь дело с вещами, которые не гарантированно являются текстовыми (например, имена файлов), вы можете добавить тестовый пример для него. Как с с:
test=$(printf '\200\n\200')
в локали UTF-8.