Quero que o meu bash imprima 'encontrado' apenas se algo for encontrado, usando o comando find. Mas usar && não ajuda: mesmo que não tenha encontrado nada, estou sendo 'encontrado' impresso. Exemplo:
$ pwd
/data/data/com.termux/files/home/test/test1/test4
$ ls
xaa xab
$ find . -name xac && echo 'found'
found
$ find . -name xaa && echo 'found'
./xaa
found
command-line
find
Josef Klimuk
fonte
fonte
/some/path
diz para descobrir onde começar a procurar, mas nada diz o que procurar. O mesmo na sua resposta vinculada. O que funciona para mim éfind /some/path -name xac -print0 -quit | grep -qz . && echo found
. Perdi algo?-print0 -quit
. O que você coloca antes disso depende do que deseja encontrar. Eu escolhi omitir isso aqui.A resposta de muru é apropriada e adequada para os casos em que queremos imprimir algo se o arquivo for encontrado. Para casos gerais, quando queremos executar um comando externo, como
echo
, poderíamos usar-exec
flag.A
{}
parte passa o nome do arquivo para o comando entre-exec
e\;
como argumentos. Observe o\
antes;
- ele impede que o shell o interprete errado ; no ponto e vírgula de fechamento do shell significa fim do comando, mas quando escapado com barra, o shell o tratará como texto literário a ser passado aofind
comando e, para encontrar o comando, ele serve como-exec
argumento de fechamento da flag.Para construir condicionais do
if found do this; else do that
tipo, poderíamos fazer uso da subestação de comando$()
etest
comando (aka[
):Dirigindo-se ao comentário de Dan
Dan nos comentários perguntou:
Vamos entender o problema primeiro. Normalmente, em shells existe o conceito de divisão de palavras, o que significa que variáveis não citadas e parâmetros posicionais serão expandidos e tratados como itens separados. Por exemplo, se você tiver variável
var
e contémhello world
texto, quando você faztouch $var
o shell vai dividi-la em dois itens separadoshello
eworld
etouch
vai entender que, como se estivesse tentando criar 2 arquivos separados; se o fizertouch "$var"
, o shell trataráhello world
como uma unidade etouch
criará apenas um arquivo. É importante entender que isso acontece apenas devido à forma como as conchas funcionam.Por outro lado,
find
não sofre com esse comportamento, porque os comandos são processados porfind
si só e executados porexecvp()
chamada do sistema, portanto, não há shell envolvido. Enquanto os chavetas têm um significado especial nas conchas, porque elas aparecem no meio dofind
comando e não no começo, elas não possuem significado especial para descascar nesse caso. Aqui está um exemplo. Vamos criar alguns nomes de arquivos difíceis e tentar transmiti-los como argumento parastat
comando.Como você pode ver,
stat
recebe nomes de arquivos difíceis perfeitamentefind
, o que é um dos principais motivos pelos quais é recomendado para uso em scripts portáteis e especialmente útil quando você está percorrendo a árvore de diretórios e deseja fazer algo com nomes de arquivos que possam ter potencialmente caracteres especiais neles. Portanto, não é necessário citar chaves para comandos executados nofind
.É uma história diferente quando a shell se envolve. Às vezes, você precisa usar um shell para processar o nome do arquivo. Nesse caso, a citação será realmente importante, mas é importante perceber que o problema não é do achado - é o shell que faz a divisão de palavras.
Então, quando citamos dentro do shell , ele funcionará. Mas, novamente, isso é importante para o shell, não
find
.fonte
echo "I found {}"
seria melhor do queecho "I found " {}
? Talvez para eco seja bom, mas se alguém copia o comando e substitui o eco por outro comando, pode haver um problema.