Primeiro exemplo
$ ffind $intVal
'' is not a valid resource
Isso não funciona porque $foo é a sintaxe das variáveis e você não tem uma variável chamada intVal set, portanto $intVal é traduzido para uma string vazia. Como a variável também é sem aspas, nenhum argumento é passado para ffind .
Para corrigir isso, escape do $ - ou \$intVal (barra invertida) ou '$intVal' (citação simples).
Se você realmente tiver uma variável chamada intVal , coloque duplo em vez disso - "$intVal" - isso será expanda o valor da variável, mas não a dividirá.
Note que não existe tal coisa como "passar por referência" no bash. Há apenas passagem por valor e (complicado) passo a passo.
Segundo exemplo
$ ffind "testing :"
bash: [: testing: unary operator expected
'testing :' is not a valid resource
Isso não funciona porque você esqueceu de colocar aspas em torno de $1 na linha if [ $1 ] , portanto, está sujeito a divisão de palavras e três argumentos são passados para o [ builtin:
- "
[" - "
testing" - "
:" - "
]"
em vez dos dois esperados:
- "
[" - "
testing :" - "
]"
O Exemplo # 1 também é afetado por isso, pois [ $1 ] divide em (" [ ", " ] ") e não (" [ ", " ", " ] "). Exemplo # 1 funciona por acidente, no entanto, já que aparentemente [ ] é válido. (Eu não sabia disso ...)
Para corrigir esse problema, coloque aspas duplas em torno de $1 - [ "$1" ] .
Observação: Embora [ seja padrão, há também um operador [[ específico do bash, que na verdade tem regras de análise diferentes do resto do código - em particular, não dividir variáveis expandidas. No bash, [[ $1 ]] e [[ "$1" ]] são equivalentes, ao contrário de suas alternativas [ .
Mais bugs
Sua função também tem vários outros problemas que não são mostrados nos exemplos.
find -type f | grep -ir '$1' * | grep -v '.svn'
Nesta linha:
-
A palavra
'$1'tem aspas simples ao redor. Isso significa que o bash não expandirá seu conteúdo - você está realmente dizendo grep para procurar o regex$1, e não o argumento da linha de comando.Para corrigir isso, use aspas duplas -
"$1" -
O primeiro comando grep está sendo solicitado para pesquisar recursivamente o conteúdo de todos os arquivos no diretório atual (
-re*curinga).Ao mesmo tempo, você está canalizando a saída de
find -type fpara grep - aparentemente tentando dizer grep para pesquisar os nomes de todos os arquivos.Isso não funcionará porque grep , como a maioria dos filtros, não lerá de stdin se receber um ou mais arquivos para pesquisar. Eu não sei o que você está tentando pesquisar - nomes de arquivos ou conteúdo de arquivos - então escolha um:
-
Para procurar apenas nomes de arquivos, mantenha o pipe, mas remova a especificação do arquivo:
find -type f | grep -i "$1" | ... -
Para pesquisar apenas o conteúdo do arquivo, remova o
find|:grep -ir "$1" * | ... -
É possível combinar ambos, explicitamente dando grep o arquivo "stdin":
find -type f | grep -i "$1" - * | ... find -type f | grep -i "$1" /dev/stdin * | ...(
/dev/stdinfunciona com todos os programas Linux, enquanto-é uma convenção usada por alguns programas, incluindo o grep.)
-
-
No segundo comando grep , a regex de pesquisa é um pouco ampla demais. (Lembre-se de que é uma regex, não uma string fixa).
.svncorresponderia a algo como "not-a-svn-file".Para excluir o diretório
.svn, usegrep -v "/\.svn/".Se pesquisar o arquivo conteúdo (
grep -ir ...), é melhor livrar-se do comandogrep -ve adicionar--exclude-dir=".svn"ao primeiro.
Você pode parar de ler neste ponto
Os itens abaixo são apenas uma boa prática nos scripts sh .
-
A palavra-chave
functioné desnecessária:ffind() { ...é suficiente e funciona em todos os shells do POSIX (enquantofunction ffindnão seria ). -
Se um script, programa ou função falhar, ele deve retornar um status de "falha" para seu pai. Por convenção, os programas Unix consideram
0como "sucesso" e qualquer outra coisa "falha" (embora haja exceções para o último).Para retornar um status explicitamente, use
return <num>em uma função (ouexit <num>em um script independente):else echo "'$1' is not a valid resource" >&2 return 1 fi -
Da mesma forma, as mensagens de erro não devem ser misturadas com stdout normal, mas gravadas em stderr (fd # 2), usando o operador de redirecionamento
>&(veja o exemplo acima). Dessa forma, você pode redirecionar a saída normal para um arquivo (por exemplo,ffind intVal > results.txt) enquanto ainda apresenta erros na tela.
Código fixo
ffind()
{
if [ "$1" ] ; then
grep -ir --exclude-dir=".svn" "$1" .
else
echo "'$1' is not a valid resource" >&2
return 1
fi
}
Melhores ferramentas
ack afirma ser "melhor que o grep". A execução de ack "testing :" pesquisaria seu código-fonte e ignoraria automaticamente .svn e diretórios semelhantes.