Estou escrevendo um script que precisa verificar se algum arquivo em um determinado diretório foi modificado recentemente. Achei que poderia simplesmente usar find
, mas ele relata sucesso mesmo que não encontre uma correspondência:
$ touch afile
$ find . -mtime -1 -iname ????*
./afile
$ echo $?
0
$ find . -mtime +1 -iname ????*
$ echo $?
0
(Estou apenas usando o predicado iname para excluir '.' aqui - mas o mesmo comportamento com -type f
)
Eu preferiria não ter que analisar a saída, ls
pois isso pode ser temperamental .
Usar test -n "$(find . -mtime -1 -iname ????*)"
parece dar o resultado desejado, mas não me parece uma solução particularmente elegante.
Não preciso saber quais arquivos foram modificados - apenas se ALGUM tiver sido alterado recentemente (onde "recentemente" geralmente será de 1 dia).
Existe uma maneira melhor de fazer isso?
(pesquisando no Google, encontro muitas porcarias de SEO sobre como executar uma busca simples)
Sim, como você viu, você não pode usar o código de saída do find para algo assim. O código de saída é apenas sobre se o comando foi executado com sucesso ou não, não tem nada a ver com o fato de os arquivos terem sido encontrados ou não. Afinal, não encontrar nenhum arquivo não é um fracasso, é um sucesso: você obteve o resultado correto, nenhum arquivo. Isso é explicado em
man find
(a citação é do GNU find):Você realmente poderia usar
-n $(find ...)
, não vejo problema nisso. Como os nomes dos arquivos não podem conterNUL
, não consigo pensar em um caso que possa quebrar isso. Se você quiser algo um pouco mais limpo, tente usar um array e depois testar se o número de elementos no array é maior que0
. Algo assim:Francamente, porém, não tenho certeza se isso é melhor do que o mais simples
[[ -n $(find ...) ]] && echo found || echo nope
.mtree
foi projetado especificamente para esse tipo de coisa, como verificar se um diretório cheio de binários não foi substituído por código malicioso ou corrompido ou qualquer caso de uso em que você deseja verificar se um conjunto de arquivos está livre de alterações inesperadas (seja em dados ou metadados).Crie (
-c
) um arquivo de referênciamy_dir.mtree
do seu diretório (-p my_dir
), incluindo o-K sha256
resumo:Na próxima vez que você quiser verificar se algum arquivo foi modificado, execute
mtree
novamente fornecendo apenas a-p
opção de caminho e seu arquivo de especificação mtree:Quaisquer arquivos diferentes serão listados.
Com zsh,
() {body} args
define e executa uma função anônima cujo corpo aqui é a(($#))
expressão aritmética que retorna verdadeiro se$#
(o número de argumentos) for diferente de zero**/
qualquer nível (incluindo 0) de diretórios, abreviação de extendedglob's(*/)#
. Observe que.
ele próprio não é considerado, você pode substituir**/
por{.,**/}
se quiser que seja considerado.N
: qualificador nullglob glob : não reclame se não houver correspondência e, em vez disso, passe uma lista vazia para a função anônima.D
: dotglob, não pule arquivos ocultos.Y1
: pare na primeira partida como uma otimizaçãom-1
: últimam
odificação no último dia (24 horas) comofind
's-mtime -1
.Com
set -o extendedglob
, você pode usar?(#c4,)
em vez de????*
para corresponder arquivos com pelo menos 4 caracteres em seus nomes.Pode ser um pouco mais eficiente se houver um grande número de arquivos correspondentes, pois
grep -q
será encerrado assim que ler uma linha de entrada, após o quefind
será eliminado na próxima vez que gravar algo no canal.Como
find
irá armazenar em buffer sua saída quando ela for para um canal, ela não será eliminada assim que o primeiro arquivo for encontrado.Com GNU ou FreeBSD
find
, você pode fazer:No NetBSD, o equivalente é com
-exit
. Com GNUfind
, você pode substituir-print
por-printf .
uma pequena otimização.Você também pode fazer coisas como:
Onde
find
invocash
para gerar algo e matar seu pai.