Jak skopiować wszystkie pliki do folderu z wyjątkiem plików, które są zapisywane?

12

Pobieram wiele plików do folderu downloadingprzez HTTPie . Skrypt bash ma na celu przetwarzanie pobranych plików, a ja próbowałem skopiować pobrane pliki do innego folderu jako

find /folder/downloading -type f -exec mv '{}' /folder/downloaded \;

ale powoduje to również skopiowanie plików, które nie zostały jeszcze ukończone. Próbowałem ograniczyć transfer do starszych plików, dodając -mmin +5do polecenia. Jakie jest skuteczne polecenie, aby opuścić pliki są zapisywane i przesyłać tylko pobrane pliki?

Googlebot
źródło
Jeśli kopiujesz do tego samego systemu plików, a ustawisz, aby downloader nie zmieniał nazwy (pobierz, %.parta następnie zmień nazwę na%). Jeśli więc program pobierający zachowuje się dobrze (nie robi nic dziwnego), powinieneś mieć możliwość zmiany nazw mvplików ( ).
ctrl-alt-delor
1
Jakiego rodzaju przetwarzanie próbujesz wykonać? Najprawdopodobniej dostępna jest znacznie prostsza opcja, na przykład użycie potoku.
ogrodnik

Odpowiedzi:

11

Niezbyt wydajny, ale możesz zrobić:

find /folder/downloading -type f -exec sh -c '
  for file do
    lsof -F a "$file" | grep -q w || mv "$file" /folder/downloaded
  done' sh {} +

Czyli sprawdzenie, czy plik nie jest wymieniony w wobrządku atrybie OSTĘP w lí st opiórkowych files zanim mo ving.

psmiscWdrożenie fuserjak zwykle znajduje się na systemach operacyjnych Linux opartych posiada -wfunkcję (w celu sprawdzenia otwartych plików na piśmie), ale niestety tylko z pracy -k, aby zabić odpowiednich procesów. Wydaje się jednak, że nadal możesz go używać, używając pseudo-sygnału 0, który nic nie robi:

find /folder/downloading -type f -exec sh -c '
  for file do
    fuser -s -w -k -0 "$file"  || mv "$file" /folder/downloaded
  done' sh {} +

Usuń -s(lub nawet zamień na -v), jeśli chcesz zobaczyć, jakie procesy uniemożliwiają przeniesienie.

Pamiętaj, że jeśli nie uruchamiasz tych komend jako superużytkownik, otrzymasz jedynie informacje o swoich procesach. Jeśli procesy pobierające pliki działają jako inny użytkownik, pozostaną niewykryte.

Pamiętaj również, że jeśli nie przenosisz plików do innego systemu plików, przeniesienie plików nie uniemożliwi ukończeniu przez proces zapisujący pliku tego pliku.

Jednakże, w zależności od tego, co już zostało zaprojektowane, aby zrobić potem, że może się mylić, jeśli po zakończeniu ich pisanie, plik nie jest już tam (na przykład, jeśli chcą zmienić niektóre atrybuty pliku po pobraniu go i tak nie nie poprzez deskryptor pliku (jak chmod()vs fchmod(), lub utimes()którego nie można zrobić za pomocą deskryptora pliku)).

Stéphane Chazelas
źródło
Pytanie shellowe: Myślę, że rozumiem twój kod z jednym wyjątkiem. -execPracuje shz jednego polecenia ( -c '...') i {} +mówi to, aby umieścić więcej niż jeden wynik do tego polecenia w czasie. Nie rozumiem tylko, dlaczego shpo poleceniu jest inny . czego mi brakuje?
Joe
2
@Joe, to właśnie wchodzi w skład skryptu wbudowanego $0. Oznacza to, że nadaje nazwę temu wbudowanemu skryptowi. Ta nazwa może być używana w komunikatach o błędach, takich jak <name>: fuser: command not foundna przykład, więc shogólnie jest dobrym wyborem w tym przypadku, aby wyjaśnić, co zgłasza ten komunikat o błędzie (tak też by było, gdybyśmy nie podali żadnego argumentu po skrypt wewnętrzny).
Stéphane Chazelas