จากlsof
หน้าคน
Lsof ส่งคืนหนึ่ง (1) หากตรวจพบข้อผิดพลาดใด ๆ รวมถึงความล้มเหลวในการค้นหาชื่อคำสั่งชื่อไฟล์ที่อยู่อินเทอร์เน็ตหรือไฟล์ชื่อเข้าสู่ระบบไฟล์ NFS PIDs PGID หรือ UID ที่ถูกขอให้แสดงรายการ หากระบุตัวเลือก -V lsof จะระบุรายการค้นหาที่ไม่สามารถแสดงรายการได้
ดังนั้นจะแนะนำว่าlsof failed for some other reason
ประโยคของคุณจะไม่ถูกดำเนินการ
คุณลองย้ายไฟล์ในขณะที่กระบวนการภายนอกของคุณยังคงเปิดอยู่หรือไม่? หากไดเรกทอรีปลายทางอยู่ในระบบไฟล์เดียวกันก็ไม่น่าจะมีปัญหาในการทำเช่นนั้นเว้นแต่คุณจะต้องเข้าถึงมันภายใต้เส้นทางเดิมจากกระบวนการที่สามเนื่องจาก inode นั้นจะยังคงเหมือนเดิม มิฉะนั้นฉันคิดว่าmv
จะล้มเหลวอยู่ดี
หากคุณจำเป็นต้องรอจนกว่ากระบวนการภายนอกของคุณจะเสร็จสิ้นด้วยไฟล์คุณควรใช้คำสั่งที่บล็อกแทนการสำรวจซ้ำ บน Linux คุณสามารถใช้inotifywait
สำหรับสิ่งนี้ เช่น:
inotifywait -e close_write /path/to/file
หากคุณต้องใช้lsof
(อาจจะพกพาได้) คุณสามารถลองดังนี้:
until err_str=$(lsof /path/to/file 2>&1 >/dev/null); do
if [ -n "$err_str" ]; then
# lsof printed an error string, file may or may not be open
echo "lsof: $err_str" >&2
# tricky to decide what to do here, you may want to retry a number of times,
# but for this example just break
break
fi
# lsof returned 1 but didn't print an error string, assume the file is open
sleep 1
done
if [ -z "$err_str" ]; then
# file has been closed, move it
mv /path/to/file /destination/path
fi
ปรับปรุง
ตามที่ระบุไว้โดย@JohnWHSด้านล่างการออกแบบที่ปลอดภัยที่สุดจะใช้การlsof
วนซ้ำตามที่เป็นไปได้ว่ามีมากกว่าหนึ่งกระบวนการที่จะเปิดไฟล์สำหรับการเขียน (กรณีตัวอย่างอาจเป็น daemon การทำดัชนีที่เขียนไม่ดีซึ่งเปิดไฟล์ด้วยการอ่าน / เขียนการตั้งค่าสถานะเมื่อควรอ่านเท่านั้นจริง ๆ ) inotifywait
ยังสามารถนำมาใช้แทนการนอนหลับ inotifywait -e close /path/to/file
แต่เพียงแค่เปลี่ยนสายการนอนหลับที่มี