Sim,
nl='
'
case $var in
(*"$nl"*) echo yes;;
(*) echo no;;
esac
(por princípio, eu gosto de citar todas as expansões variáveis dentro do case
padrão, a menos que eu queira que elas sejam tratadas como um padrão, embora aqui não faça diferença, pois $nl
não contém curingas).
ou
case $var in
(*'
'*) echo yes;;
(*) echo no;;
esac
Todos devem funcionar e são compatíveis com POSIX, e o que eu usaria para isso. Se você remover os (
s, funcionaria até no antigo shell Bourne.
Para outra maneira de definir a $nl
variável:
eval "$(printf 'nl="\n"')"
Observe que $'\n'
está planejado para inclusão na próxima versão do padrão POSIX . Já está apoiado por ksh93
, zsh
, bash
, mksh
, busybox e FreeBSD sh
, pelo menos (em Fevereiro de 2018).
Quanto à questão de saber se o teste que você possui é suficiente, você tem um teste para os dois casos; portanto, estaria testando todos os caminhos de código.
Atualmente, existe algo que não está claramente especificado na especificação POSIX: se *
corresponde a uma sequência que contém sequências de bytes que não formam caracteres válidos ou se variáveis de shell podem conter essas sequências.
Na prática, além de yash
cujas variáveis podem conter apenas caracteres e além dos bytes NUL (que não possuem shell, mas zsh
podem armazenar em suas variáveis), *$nl*
devem corresponder a qualquer sequência que contenha, $nl
mesmo que contenham sequências de bytes que não sejam válidas caracteres (como $'\x80'
em UTF-8).
Algumas find
implementações, por exemplo, não combinariam com -name "*$nl*"
elas; portanto, se estiver testando um novo shell e se você pretende lidar com coisas que não são garantidas como texto (como nomes de arquivos), convém adicionar um caso de teste. Como com:
test=$(printf '\200\n\200')
em um código de idioma UTF-8.