Versões mais antigas de bash tinham esse bug / falta de recursos em
cat <<< $var
O conteúdo de $var passaria por uma divisão de palavras (mas não por globbing) e as palavras resultantes se juntariam a espaços antes de serem colocadas em um arquivo temporário configurado como entrada para o comando cat .
Isso foi corrigido no bash-4.4 para alinhar com os outros shells que suportam o operador <<< zsh.
Para versões mais antigas, esse é outro caso em que você precisa citar suas variáveis.
Então, se $IFS continha i ou f , isso poderia explicar a discrepância:
$ a='if' bash4.1 -c 'IFS=f; cat <<< $a'
i
$ a='if' bash4.4 -c 'IFS=f; cat <<< $a'
if
Em qualquer caso, observe que -e 'if(' é redundante, pois se um texto contiver if( como uma palavra, ele também conterá uma if word.
Observe também que bash tem correspondência de regexp integrada, portanto você sempre pode fazer
re='\<if\>'
if [[ $p =~ $re ]]; then
printf '"%s" contains a "if" word\n' "$p"
fi
(pelo menos em sistemas como o Linux Mint e RHEL em que os EREs têm \< , \> , mas se o grep suportar -w , é provável que os EREs também tenham \< e \> ).
(acima é um daqueles casos muito raros em que $p não precisa ser citado (embora a cotação não seja prejudicial), e $re não deve ser citado (caso contrário, conteúdo não é tomado como uma expressão regular, mas como uma string fixa))
Com a sintaxe sh padrão, você também pode fazer:
case +$p+ in
(*[^[:alnum:]_]if[^[:alnum:]_]*)
printf '"%s" contains a "if" word\n' "$p"
esac
Para obter o mesmo efeito.