shell script para tocar automaticamente nos arquivos

1

Eu escrevi um script de shell para tocar em todos os arquivos no diretório /tmp . No entanto, houve uma mensagem de erro dizendo que %código%. Qual é a causa do problema?

#!/bin/bash

dayNo=1
while test $dayNo -le 200
do
    touch 'find /tmp/'
    sleep 86000
done
    
por user45857 20.08.2014 / 06:30

3 respostas

4

Você tem tantos arquivos em /tmp que você não pode caber em todos os nomes na linha de comando de uma só vez (a versão que você possui também é insegura se algum caminho tiver espaço em branco).

A boa notícia é que find pode fazer isso para você de forma segura e correta:

find /tmp -exec touch -c '{}' +

encontrará todos os arquivos como antes e, em seguida, executará touch quantas vezes forem necessárias com tantos arquivos quanto couberão a cada vez.

find ' -exec option recebe um comando para executar os arquivos correspondentes e substitui os caminhos em que {} é. + significa que ele executa o comando com muitos arquivos de uma vez ou \; executaria touch uma vez para cada arquivo.

Como observado nos comentários, -execdir touch -c '{}' \; é estritamente mais seguro aqui, embora provavelmente seja um pouco mais lento, e não há muito benefício a ser obtido em um sistema de usuário único. Ele evita determinadas condições de corrida, alternando para cada subdiretório primeiro e, em seguida, executando o comando apenas para arquivos nesse diretório a cada vez. A opção -execdir é uma extensão não padrão, mas é suportada no GNU , FreeBSD , OpenBSD , NetBSD e OS X find s; os outros Unices comerciais geralmente não têm isso. Não tenho certeza do que você está usando, mas leve em conta o que precede se for aplicável.

    
por 20.08.2014 / 06:35
1

O shell substitui o resultado da expressão nos backticks na linha. Mas o sistema tem limites sobre quanto tempo uma lista de argumentos pode ser para um comando. Então, se você tem alguns milhares de arquivos em / tmp, está tentando criar um comando com milhares de nomes como argumento. Isso falha.

Existem várias maneiras de fazer isso com mais facilidade. Encontrar-se pode executar o comando. A maioria das versões modernas permite dividi-lo e executar vários comandos touch individuais, cada um abaixo do limite.

find /tmp -exec touch {} +
    
por 20.08.2014 / 06:36
0
O principal problema com a invocação do backtick na questão é que primeiro o comando find lista todos os arquivos em / tmp e passa essa lista (enorme) como argumentos para touch , o que é demais para uma única invocação. Há também um problema se os nomes de arquivos contiverem espaços, novas linhas, ponto-e-vírgula, e comercial, caracteres de canal ou similares.

Melhor usar este constructo:

find /tmp -type f -exec touch -c '{}' +

O comando find lista recursivamente todos os arquivos (diretórios, links simbólicos, especiais do dispositivo também são "arquivos" no unix) em /tmp .

-type f informa ao encontrar para selecionar apenas arquivos regulares

A opção -c para touch impede que o toque crie arquivos que não existem.

Parece que você omitiu alguma lógica no seu exemplo, mas se quiser fazer isso apenas 200 vezes, tente o seguinte:

#!/bin/bash

dayNo=1
while test $dayNo -le 200
do
    find /tmp -type f -exec touch -c '{}' +
    sleep 86000
    dayNo=$(expr 1 + ${dayNo})
done
    
por 20.08.2014 / 08:59

Tags