วิธีคัดลอกไฟล์ทั้งหมดในโฟลเดอร์โดยไม่รวมไฟล์ที่กำลังเขียนอยู่?


12

ผมดาวน์โหลดไฟล์หลายไฟล์ไปยังโฟลเดอร์ที่downloadingผ่านHTTPie สคริปต์ทุบตีมีจุดประสงค์เพื่อประมวลผลไฟล์ที่ดาวน์โหลดมาและฉันพยายามคัดลอกไฟล์ที่ดาวน์โหลดไปยังโฟลเดอร์อื่นเช่น

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

แต่ยังคัดลอกไฟล์ซึ่งยังไม่เสร็จ ฉันพยายาม จำกัด การถ่ายโอนไปยังไฟล์เก่าโดยเพิ่ม-mmin +5ไปยังคำสั่ง คำสั่งที่มีประสิทธิภาพในการปล่อยให้ไฟล์กำลังถูกเขียนและโอนย้ายไฟล์ที่ดาวน์โหลดมาเท่านั้น?


หากคัดลอกไปยังระบบไฟล์เดียวกันและคุณตั้งค่าตัวดาวน์โหลดให้ไม่เปลี่ยนชื่อ (ดาวน์โหลด%.partแล้วเปลี่ยนชื่อเป็น%) จากนั้นหากตัวดาวน์โหลดทำงานได้ดี (ไม่ทำอะไรแปลก ๆ ) คุณควรจะสามารถเปลี่ยนชื่อmvไฟล์( ) ได้
ctrl-alt-delor

1
คุณกำลังพยายามประมวลผลแบบใด มีแนวโน้มที่จะมีตัวเลือกที่ง่ายกว่าเช่นการใช้ไปป์ไลน์
gardenhead

คำตอบ:


11

ไม่มีประสิทธิภาพมาก แต่คุณสามารถทำได้:

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

นั่นคือการตรวจสอบว่าไฟล์ไม่ได้อยู่กับwพระราชพิธีaโหมด ccess ในlฉันsทีของoปากกาfไมล์ก่อนmo vไอเอ็นจี

การpsmiscใช้งานfuserตามปกติที่พบในระบบปฏิบัติการที่ใช้ Linux มี-wฟังก์ชั่น (เพื่อตรวจสอบไฟล์ที่เปิดสำหรับการเขียน) แต่น่าเสียดายที่มันทำงานร่วมกับ-kเพื่อฆ่ากระบวนการที่สอดคล้องกันเท่านั้น อย่างไรก็ตามดูเหมือนว่าคุณยังสามารถใช้งานได้โดยใช้สัญญาณหลอก 0 ที่ไม่ทำสิ่งใดเลย:

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

ลบ-s(หรือแทนที่ด้วย-v) หากคุณต้องการดูว่ากระบวนการใดที่ป้องกันการย้าย

โปรดทราบว่าหากคุณไม่ได้ใช้คำสั่งเหล่านั้นในฐานะผู้ใช้ขั้นสูงคุณจะได้รับข้อมูลเกี่ยวกับกระบวนการของคุณเท่านั้น หากกระบวนการดาวน์โหลดไฟล์กำลังทำงานในฐานะผู้ใช้คนอื่นกระบวนการเหล่านั้นจะยังคงไม่ถูกตรวจจับ

นอกจากนี้โปรดทราบว่าหากคุณไม่ย้ายไฟล์ไปยังระบบไฟล์ที่แตกต่างกันการย้ายไฟล์จะไม่ป้องกันกระบวนการใดก็ตามที่กำลังเขียนไปยังไฟล์ไม่ให้ทำการเขียนลงไฟล์

อย่างไรก็ตามขึ้นอยู่กับสิ่งที่พวกเขาได้รับการออกแบบให้ทำหลังจากนั้นพวกเขาอาจจะสับสนถ้าหลังจากเขียนเสร็จแล้วไฟล์จะไม่อยู่ที่นั่นอีกต่อไป (ตัวอย่างเช่นหากพวกเขาต้องการเปลี่ยนคุณลักษณะบางอย่างของไฟล์หลังจากดาวน์โหลดและไม่ผ่าน file descriptor (เช่นchmod()vs fchmod()หรือutimes()ซึ่งไม่สามารถทำได้ผ่าน file descriptor)


คำถาม Shell: ฉันคิดว่าฉันเข้าใจโค้ดของคุณด้วยข้อยกเว้นหนึ่งข้อ -execกำลังทำงานshกับคำสั่งหนึ่ง ( -c '...') และ{} +บอกว่ามันจะใส่มากกว่าหนึ่งผลลงในคำสั่งที่ได้ตลอดเวลา สิ่งที่ฉันไม่เข้าใจคือเหตุผลว่าทำไมมีอีกshหลังจากคำสั่ง ฉันกำลังคิดถึงอะไร
Joe

2
@ Joe $0ว่าเป็นสิ่งที่จะเข้าสู่การของอินไลน์สคริปต์ นั่นคือจะให้ชื่อสคริปต์แบบอินไลน์นั้น ชื่อที่อาจจะนำมาใช้ในข้อความผิดพลาดเหมือน<name>: fuser: command not foundเช่นดังนั้นshโดยทั่วไปเป็นทางเลือกที่ดีในกรณีนี้จะทำให้มันชัดเจนว่ามีการรายงานข้อผิดพลาดที่ (ที่ยังมีสิ่งที่มันจะถ้าเราไม่ได้ให้การโต้แย้งใด ๆ หลังจากที่ อินไลน์สคริปต์)
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.