O shell Bourne tinha uma construção para isso. É o mesmo que no moderno sh
(que parece mais com o que você está usando, o shell Bourne não tinha suporte para $(...)
; se fosse o shell Bourne, você receberia um erro diferente):
case $1 in
*"$2"*) printf '"%s" is in "%s"\n' "$2" "$1"
esac
Se você quisesse usar grep
, seria:
if printf '%s\n' "$1" | grep -Fqe "$2"; then
printf '"%s" is in "%s"\n' "$2" "$1"
fi
Ou
if grep -Fqe "$2" << EOF
$1
EOF
then
printf '"%s" is in "%s"\n' "$2" "$1"
fi
Mas isso só funcionaria corretamente se $2
não contivesse nenhum caractere de nova linha.
Em qualquer caso, você precisa de aspas em torno da maioria dessas expansões de parâmetros. O único lugar onde não é necessário está em case $1
acima, mas mesmo assim case "$1"
não prejudicaria.
Algumas notas no seu código:
-
Você não pode usar
echo
para strings arbitrárias . Aqui, dependendo da implementação deecho
, ele falharia nos valores de$1
como-n
oufoo\bar
. -
Deixar uma expansão de parâmetro sem aspas tem um significado muito especial em shells . Você não quer fazer isso. Tente, por exemplo, que
grep -c $2
com um valor de$2
como*
ouroot /etc/passwd
. -
grep
sem-F
é para correspondência de expressões regulares. Você precisa de-F
para pesquisa de cadeia fixa (substring) (costumava ser comfgrep
), mas novamente se$2
contiver várias linhas, que dizgrep -F
para pesquisar qualquer do conteúdo dessas linhas na entrada (grep -F $'a\nb'
procurariaa
oub
, não a$'a\nb'
string). - Em
grep -c $2
, o conteúdo de$2
seria considerado uma opção se fosse iniciado com-
. Você quer quegrep -c -e "$2"
ougrep -c -- "$2"
evite isso. - Você deseja usar o status de saída, não stdout, para relatar condições booleanas. Em scripts com
exit
(exit 0
para true,exit 1
(ou qualquer número diferente de zero, mas evite valores maiores que 120) para false). Para funções, usereturn
. Embora os scripts e funções retornem com o status do último comando de execução. -
$(cmd)
expande para a saída decmd
(e passa por split + glob aqui por causa das aspas faltantes novamente) menos os caracteres de nova linha à direita. Portanto, secmd
produzir0\n
,$(cmd)
se expandirá para0
. Portanto, executar$(cmd)
tenta executar o comando chamado0
. Se você quiser converter a saída decmd
em um status de saída (para que possa ser usado como booleano), você precisará de(exit "$(cmd)")
. Isso inicia um subshell que sai com a saída decmd
como seu código de saída). -
grep -c
conta o número de ocorrências. Aqui você não precisa ter a contagem completa, você só precisa saber se ela é encontrada (se houver pelo menos uma partida). Para essegrep -q
é mais eficiente, pois deixa de procurar depois de encontrar um. Para antigas implementações degrep
que não suportam a opção (padrão)-q
, você pode usarfgrep -le "$2" > /dev/null
. Com-l
,fgrep
também pára na primeira correspondência, mas exibe o nome do arquivo (que descartamos aqui, redirecionando a saída para/dev/null
).