在OS X和Ubuntu上实时观看文件系统


11

我正在寻找一个CLI工具,该工具将监视目录并吐出实时更改的文件名。

some_watch_command /path/to/some/folder | xargs some_callback

我知道inotifyinotify-tools?),这似乎是我所需要的,但是我需要既与Linux(在我的情况下为Ubuntu)又与OSX兼容的东西。

它并不需要很快,但是确实需要触发更改(在一秒钟之内是合理的)。另外,我不一定需要上面提到的确切的CLI程序。如果存在一些基础技术并且可以在两个平台上轻松编写脚本,那也将很棒。


1
我喜欢fswatchOS X的,我对被标记为重复问题发现- superuser.com/questions/445907/...
CWD

Answers:


11

OS X通常会使用文件夹操作launchd会完成这个任务。

我知道的唯一跨平台工具是看门狗API用于Python(因此可用于OS X和Linux)。通过pip(或easy_install)安装

pip install watchdog

它带有watchmedo命令行工具,它使您可以在系统事件上运行shell命令。使用以下命令检查其常规语法watchmedo --help

这是一个简短的示例,您可以在其中轻松修改以粗体突出显示的命令和路径:

watchmedo shell命令
    -递归\
    --command =' echo“ $ {watch_src_path}” '\
     / some / folder

这只会吐出所有已更改文件或文件夹的路径,从而使您可以将watchmedo输出输出到另一个shell命令。


看起来Folder Actions有一些限制(并且在没有OSX的情况下很难测试),但是watchmedo对我来说效果很好。谢谢!
Adrian Schneider

2

我已经对一些Ruby脚本进行了调整,以完全满足您的需求。这是Ruby代码:

#!/usr/bin/ruby
# Inspired by http://vikhyat.net/code/snippets/#watchfile

# How to use:
# This script takes two paramaters:  a folder and a shell command
# The script watches for when files in the folder are changed.  When they are, the shell command executes
# Here are some shortcuts you can put in the shell script:
# %F = filename (with extension)
# %B = base filename (without extension)


unless ARGV.length == 2
  puts "\e[32m    Usage: \e[0mruby OnSaveFolder.rb 'folder' 'command'"
  exit
end

require 'digest/md5'
require 'ftools'

$md5 = ''
$directory = File.expand_path(ARGV[0])
$contents = `ls #{$directory}`
$contentsList = $contents.split("\n")
$fileList = []


Dir.chdir($directory)

for i in $contentsList
  if ( File.file?(File.expand_path(i)) == true)
    $fileList.push(i)
  end
end

$processes = []

def watch(file, timeout, &cb)
  $md5 = Digest::MD5.hexdigest(File.read(file))
  loop do
    sleep timeout
    if ( temp = Digest::MD5.hexdigest(File.read(file)) ) != $md5
      $md5 = temp
      cb.call(file)
    end
  end
end

puts "\e[31m Watching files in folder \e[34m #{$directory}"
puts "\e[32m    Press Control+C to stop \e[0m"

for i in $fileList
  pid = fork do
    $num = 0
    $filePath = File.expand_path(i)

    watch i, 1 do |file|
      puts "\n     #{i} saved"

      $command = ARGV[1].dup
      if ( ARGV[1].include?('%F') )
        $command = $command.gsub!('%F', i)
      end
      if ( ARGV[1].include?('%B') )
        $command = $command.gsub!('%B', File.basename(i, '.*'))
      end

      $output = `#{$command}`
      if ( $output != '')
        puts "\e[34m     #{$command}\e[31m output: \e[0m"
        puts $output
      end
      puts "\e[34m     #{$command}\e[31m finished \e[0m (#{$num}, #{Time.now})\n"
      $num += 1

    end
  end
  $processes.push(pid)
end

Process.wait(pid)

for i in $processes
  `kill #{i}`
end

我将此脚本命名为“ OnSaveFolder.rb”。它有两个参数:要监视更改的文件夹,以及发生更改后要运行的bash代码。例如,

ruby OnSaveFolder.rb '/home/Movies' 'echo "A movie has been changed!"'

我希望这有帮助!我发现ruby对于这种类型的东西非常有效,并且默认情况下已安装在OS X上。


给它一个镜头,但是在没有任何Ruby背景的情况下很难调整。不管怎么说,还是要谢谢你!
Adrian Schneider

这很棒。任何想法如何使其递归地查看下面的文件夹?
Nate Flink

如果我不关心更改时命令的执行,这将是多平台的,还是仅是unix?它实际上是实时的吗?一些文件查看器在那里有一个荒谬的延迟(分钟)。
Automatico

2

您可以lsof输入watch命令并使其每秒钟更新一次<s>

watch -n <s> lsof

并使用任何过滤器启动该过滤器,例如观看pid1,pid2,pid3和忽略pid4

lsof -p "pid1,pid2,pid3,^pid4"

如果这还不够的话,您总是可以使用grep编写自己的过滤器。

对于OS X,请参阅此问题的答案。


0

entr很好。您可以像这样过滤您想要观看的确切文件。

find . -name '*.py' | entr python runTests.py

如果您希望它仅监视目录中的某些文件,则可以制作 find命令,使其仅返回要查看的文件。

我发现它比容易配置fswatch

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.