Embora você tenha a opção de usar a funcionalidade de shell embutida para verificar se a entrada do usuário continha @ (o que é bem documentado nas outras respostas), outra maneira razoável de fazê-lo é com o grep utilitário:
#!/usr/bin/env bash
read -erp '> '
if grep -q @ <<<"$REPLY"; then
echo pass
else
echo fail
fi
A passagem do sinal -q para grep impede a impressão de linhas correspondentes. (Ele também impede que ele leia mais linhas depois de encontrar uma correspondência, mas isso não faz diferença aqui, pois há apenas uma linha de entrada.)
É tentador reduzir o if para algo como grep -q @ <<<"$REPLY" && echo pass || echo fail , mas evitei deliberadamente:
-
Nesse caso , provavelmente está tudo bem, já que a única maneira de imprimir a palavra errada é se
pass deveria ser impresso e echo não conseguiu imprimi-la. Então, presumivelmente, o eco não conseguiria imprimir fail também.
- Embora o curto-circuito
&& e || sejam geralmente apropriados (e eu os uso frequentemente para abreviar uma if sem uma cláusula else ), usando-os juntos como se eles eram um operador ternário if não é realmente um bom hábito. Embora alguns comandos não possam falhar , echo pode .
- Se o usuário redireciona a saída do seu script para um arquivo ou dispositivo não gravável, ou o usa em um quebrado pipeline , echo e outros comandos que emitem texto podem retornar falhas, causando falha na expressão
&& e o lado direito da expressão || para executar.
- Você pode testar o comportamento de um script na presença de um dispositivo de saída não gravável, executando-o com
>/dev/full .
Esse script usa alguns recursos bash:
-
-e ativa a linha de leitura GNU, para que o usuário possa mover o cursor para a esquerda e para a direita com as teclas de seta para editar sua entrada ao inseri-la.
- No bash,
read coloca automaticamente a entrada do usuário na variável REPLY se nenhuma variável foi fornecida.
- Uma string aqui com
<<< é uma maneira conveniente de passar o usuário entrada para grep .
- Bash e alguns outros shells no estilo Bourne, como traço, aceitam
-p . Mas os shells compatíveis com POSIX precisam apenas entender -r . E, em alguns, como o ksh, -p tem um significado diferente.
(Obrigado ao geirha por apontar tanto que -p às vezes está ausente e que nem sempre significa" prompt ". )
Se você quiser um script que seja portátil em outros sistemas operacionais que possam não ter o bash instalado, use:
#!/bin/sh
printf '> '
read -r line
if printf '%s' "$line" | grep -q @; then
echo pass
else
echo fail
fi
Se quiser, você pode pular o armazenamento da entrada do usuário em uma variável lendo-a com head em vez de read :
#!/bin/sh
printf '> '
if head -1 | grep -q @; then
echo pass
else
echo fail
fi
Como geirha mencionou , head -n 1 pode ser considerada uma sintaxe melhor, pois head -1 é oficialmente obsoleto (embora% atualsed implementations, ou pelo menos o GNU sed, suporta -1 em suas versões mais recentes, enquanto algumas implementações sed muito antigas não suportam -n 1 ).
Como a documentação de head diz, você pode usar sed em vez de portabilidade máxima.
#!/bin/sh
printf '> '
if sed 1q | grep -q @; then
echo pass
else
echo fail
fi