【问题标题】:Run a shell command when a file is added添加文件时运行 shell 命令
【发布时间】:2012-06-12 23:23:35
【问题描述】:

我的 linux 机器上有一个名为 images 的文件夹。 此文件夹已连接到网站,并且该网站的管理员可以向该网站添加图片。但是,当添加图片时,我希望运行一个命令来调整目录中所有图片的大小。

简而言之,我想知道如何在将新文件添加到特定位置时让服务器运行特定命令。

【问题讨论】:

标签: linux bash shell cron


【解决方案1】:

我不知道人们是如何将内容上传到此文件夹的,但您可能希望使用比使用 inotify 监控目录的技术更低的东西。

如果协议是 FTP 并且您可以访问 FTP 服务器的日志,我建议跟踪该日志以观察是否成功上传。这种事件触发的方法比使用传统 cron 的轮询方法更快、更可靠、负载更少,并且比使用 inotify 的方法更便携和更容易调试。

您处理此问题的方式当然取决于您的 FTP 服务器。我有一个正在运行的vsftpd,它的日志包括这样的行:

Fri May 25 07:36:02 2012 [pid 94378] [joe] OK LOGIN: Client "10.8.7.16"
Fri May 25 07:36:12 2012 [pid 94380] [joe] OK UPLOAD: Client "10.8.7.16", "/path/to/file.zip", 8395136 bytes, 845.75Kbyte/sec
Fri May 25 07:36:12 2012 [pid 94380] [joe] OK CHMOD: Client "10.8.7.16", "/path/to/file.zip 644"

UPLOAD 行仅在 vsftpd 成功保存文件后添加。你可以像这样在 shell 脚本中解析它:

#!/bin/sh

tail -F /var/log/vsftpd.log | while read line; do
  if echo "$line" | grep -q 'OK UPLOAD:'; then
    filename=$(echo "$line" | cut -d, -f2)
    if [ -s "$filename" ]; then
      # do something with $filename
    fi
  fi
done

如果您使用的是 HTTP 上传工具,请查看该工具是否有用于记录传入文件的文本日志文件。如果它不考虑为其添加某种记录器功能,那么它将生成您可以tail 的日志。

【讨论】:

  • 这是完美的。我实际上使用了一个 php/html 上传按钮。但我可以从 apache 扫描访问文件以获取上传页面。
  • 我在这里看不到的是你正在做什么来触发跟踪日志文件的脚本。
  • @JasonGray,您熟悉tail-F 选项吗? man tail 了解详情。 -F 导致 tail 等到文件增长,然后将其发送到标准输出。所以
    do something
    部分的“触发器”只是将新内容添加到文件中。该脚本运行一次,可能在启动时运行,然后继续运行。如何启动它取决于您,并且取决于您的操作系统或发行版。
【解决方案2】:

就像 John 评论的那样,inotify API 是一个起点,但是您可能对一些使用此 API 来执行文件通知任务的工具感兴趣:

例如incron,可用于在检测到文件或目录更改时运行类似 cron 的任务。

inotify-tools,这是一组命令行工具,您可以使用它们来构建自己的文件通知 shell 脚本。

如果您查看 Wiki pake 的 inotify-tools 底部,您会看到对更多工具的引用以及对 Python、Perl 或 Ruby (example code) 等高级语言的支持。

【讨论】:

    【解决方案3】:

    你可能想看看inotify

    inotify API 提供了一种监控文件系统事件的机制。 Inotify 可用于监视单个文件或监视目录。当一个目录被监视时,inotify 将返回目录本身的事件,以及目录中的文件。

    【讨论】:

      【解决方案4】:
      #!/bin/bash
      
      tail -F -n0 /var/log/vsftpd.log | while read line; do
        if echo "$line" | grep -q 'OK UPLOAD:'; then
          filename=$(echo $line | cut -d, -f2 |awk '{print $1}')
          filename="${filename%\"}"
          filename="${filename#\"}"
          #sleep 1s
          if [ -s $filename ]; then
            # do something with $filename
            echo $filename
          fi
        fi
      done
      

      【讨论】:

      • 我赞成,因为它使用 tail -F -n0 等待新行而不处理现有行。
      【解决方案5】:

      使用 ghotis 工作

      这是我为获得用户可用空间所做的:

      #!/bin/bash
      
      tail -F -n 1 /var/log/vsftpd.log | while read line; do
        if echo "$line" | grep -q 'OK LOGIN:'; then
          pid=$(sed 's/.*\[\([^]]*\)\].*/\1/g' <<< "$line")
          #the operator '<<<' doesnt exist in dash so use bash
          if [[ $pid != *"pid"* ]]; then
            echo -e "Disk 1: Contains Games:\n" > /home/vftp/"$pid"/FreeSpace.txt; df -h /media/Disk1/ >> /home/vftp/"$pid"/FreeSpace.txt
            echo -e "\r\n\r\nIn order to read this properly you need to use a text editor that can read *nix format files" >> /home/vftp/"$pid"/FreeSpace.txt
          fi
      echo "checked"
      #  awk '{ sub("\r$", ""); print }' /home/vftp/"$pid"/FreeSpace.txt > /home/vftp/"$pid"/FreeSpace.txt
        fi
      done
      

      【讨论】:

        【解决方案6】:

        如果文件是通过 HTTP 上传添加的,并且您的服务器是 apache,您可能需要检查 mod_security。

        它使您能够为通过 HTTP POST 进行的每次上传运行脚本。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-12-02
          • 1970-01-01
          • 1970-01-01
          • 2013-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多