Linux 添加文件时运行 shell 命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10956668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:44:31  来源:igfitidea点击:

Run a shell command when a file is added

linuxbashshellcron

提问by Cripto

I have a folder named images on my linux box. This folder is connected to a website and the admin of the site has the ability to add pictures to this site. However, when a picture is added, I want a command to run resizing all of the pictures a directory.

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

In short, I want to know how I can make the server run a specific command when a new file is added to a specific location.

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

采纳答案by ghoti

I don't know how people are uploading content to this folder, but you might want to use something lower-tech than monitoring the directory with inotify.

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

If the protocol is FTP and you have access to your FTP server's log, I suggest tailing that log to watch for successful uploads. This sort of event-triggered approach will be faster, more reliable, and less load than a polling approach with traditional cron, and more portable and easier to debug than something using inotify.

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

The way you handle this will of course depend on your FTP server. I have one running vsftpdwhose logs include lines like this:

您处理此问题的方式当然取决于您的 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"

The UPLOADline only gets added when vsftpd has successfully saved the file. You could parse this in a shell script like this:

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

If you're using an HTTP upload tool, see if that tool has a text log file it uses to record incoming files. If it doesn't consider adding some sort of logger function to it, so it'll produce logs that you can tail.

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

回答by John Lawrence

You might want to look at inotify

你可能想看看 inotify

The inotify API provides a mechanism for monitoring file system events. Inotify can be used to monitor individual files, or to monitor directories. When a directory is monitored, inotify will return events for the directory itself, and for files inside the directory.

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

回答by Casper

Like John commented the inotifyAPI is a starting point, however you might be interested in some tools that use this API to perform file notification tasks:

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

For example incronwhich can be used to run cron-like tasks when file or directory changes are detected.

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

Or inotify-toolswhich is a set of command-line tools that you could use to build your own file notification shell script.

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

If you look at the bottom of the Wiki pake for inotify-tools you will see references to even more tools and support for higher-level languages like Python, Perl or Ruby(example code).

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

回答by Kevin

Using ghotis work

使用 Ghotis 工作

Here is what I did to get the users free space:

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

#!/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/.*\[\([^]]*\)\].*//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

回答by arod

If the file is added through an HTTP upload, and if your server is apache, you might want to check mod_security.

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

It enables you to run a script for every upload made through HTTP POST.

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

回答by SiB

#!/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 }')
    filename="${filename%\"}"
    filename="${filename#\"}"
    #sleep 1s
    if [ -s $filename ]; then
      # do something with $filename
      echo $filename
    fi
  fi
done