简体   繁体   English

Bash脚本迭代目录的内容,仅移动当前未由其他进程打开的文件

[英]Bash script to iterate contents of directory moving only the files not currently open by other process

I have people uploading files to a directory on my Ubuntu Server. 我有人将文件上传到Ubuntu服务器上的目录。

I need to move those files to the final location (another directory) only when I know these files are fully uploaded. 仅当我知道这些文件已完全上传时,才需要将这些文件移动到最终位置(另一个目录)。

Here's my script so far: 到目前为止,这是我的脚本:

#!/bin/bash

cd /var/uploaded_by_users

for filename in *; do

        lsof $filename

        if [ -z $? ]; then
          # file has been closed, move it           
        else
          echo "*** File is open. Skipping..."
        fi

done

cd -

However it's not working as it says some files are open when that's not true. 但是它不起作用,因为它说不正确时某些文件已打开。 I supposed $? 我以为? would have 0 if the file was closed and 1 if it wasn't but I think that's wrong. 如果文件关闭,则将为0,否则为1,但我认为这是错误的。

I'm not linux expert so I'm looking to know how to implement this simple script that will run on a cron job every 1 minute. 我不是Linux专家,所以我想知道如何实现这个简单的脚本,该脚本每1分钟在cron作业上运行一次。

[ -z $? ] [ -z $? ] checks if $? [ -z $? ]检查$? is of zero length or not. 长度是否为零。 Since $? 由于$? will never be a null string, your check will always fail and result in else part being executed. 永远不会是一个空字符串,您的检查将始终失败并导致else部分被执行。 You need to test for numeric zero, as below: 您需要测试数字零,如下所示:

lsof "$filename" >/dev/null; lsof_status=$?
if [ "$lsof_status" -eq 0 ]; then
  # file is open, skipping
else
  # move it
fi

Or more simply (as Benjamin pointed out): 或更简单地(如本杰明指出):

if lsof "$filename" >/dev/null; then
  # file is open, skip
else
  # move it
fi

Using negation, we can shorten the if statement (as dimo414 pointed out): 使用否定,我们可以缩短if语句(如dimo414所指出的):

if ! lsof "$filename" >/dev/null; then
  # move it
fi

You can shorten it even further, using && : 您可以使用&&进一步缩短它:

for filename in *; do
  lsof "$filename" >/dev/null && continue  # skip if the file is open
  # move the file
done

You may not need to worry about when the write is complete, if you are moving the file to a different location in the same file system. 如果要将文件移动到同一文件系统中的其他位置,则可能无需担心写入完成的时间。 As long as the client is using the same file descriptor to write to the file, you can simply create a new hard link for the upload file, then remove the original link. 只要客户端使用相同的文件描述符写入文件,您就可以简单地为上传文件创建一个新的硬链接,然后删除原始链接。 The client's file descriptor won't be affected by one of the links being removed. 客户端的文件描述符不会受到链接之一被删除的影响。

cd /var/uploaded_by_users
for f in *; do
    ln "$f" /somewhere/else/"$f"
    rm "$f"
done

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM