Como mover arquivos que não estão em uso?

1

Eu quero mover arquivos em um diretório que não esteja em uso no momento. Tenho a sensação de que alguma combinação de lsof , find e xargs poderia funcionar, mas não consigo chegar lá. Até agora, criei o seguinte comando:

lsof mydir/*|awk '(NR>1){print $9}

Isso me dá uma lista de arquivos que estão sendo usados. Se eu pudesse apenas obter uma lista de arquivos que NÃO estão sendo usados, então algo como xargs poderia emitir um mv nesses arquivos. Eu simplesmente não consigo encontrar uma maneira elegante de fazer isso. Alguém tem alguma dica para mim?

    
por User1 07.12.2010 / 18:50

4 respostas

2

Graças à sugestão do @ Sorpigal, encontrei uma maneira fácil de fazer isso funcionar sem loops:

%pr_e%

Não tenho certeza das condições da corrida, mas isso não importa no meu caso. Os arquivos são abertos uma vez para gravação e depois devem ser fechados até serem movidos.

    
por 07.12.2010 / 20:58
3

Eu faria assim.

find $dir -maxdepth 1 | sort > $other_dir/all_files
lsof $dir/* | awk '(NR>1) {print $9}' | sort > $other_dir/in_use_files
comm -2 -3 $other_dir/all_files $other_dir/in_use_files

da comunicação (1):

NAME
       comm - compare two sorted files line by line

SYNOPSIS
       comm [OPTION]... FILE1 FILE2

    ...

       -2     suppress lines unique to FILE2

       -3     suppress lines that appear in both files

Agora, é uma simples reformatação em uma série de instruções mv . Talvez assim:

while IFS= read file ; do
    mv "$file" "$destination/"
done < <(comm -2 -3 all_files in_use_files)

Ou usando outro arquivo intermediário, se você preferir.

    
por 07.12.2010 / 19:55
2

Talvez não seja o melhor caminho, mas é possível codificar em alguns minutos:

obtenha sua lista de arquivos abertos (classifique se ainda não estiver)

obtenha uma lista de todos os arquivos (classifique se ainda não estiver)

diferencie as duas listas

xargs qualquer que seja

O número de etapas aqui tornará óbvio algo que deveria ser uma preocupação, de qualquer forma, que são condições de corrida - os arquivos que estão em uso quando você os seleciona podem não ser os arquivos que estão em uso quando você realmente os move.

    
por 07.12.2010 / 19:10
2

É para isso que o fusor se destina.

/var/log/apache2
$ fuser access.log
/var/log/apache2/access.log: 2132 15456 16414 19555 19622
/var/log/apache2
$ fuser access.log 2>/dev/null
 2132 15456 16414 19555 19622
/var/log/apache2
$ if [ ! -z "$(fuser access.log 2>/dev/null)" ]
> then
>   echo "this file is in use"
> else
>   echo "this file is not in use"
> fi
this file is in use
    
por 05.06.2012 / 15:58

Tags