ดูระบบไฟล์ในเวลาจริงบน OS X และ Ubuntu


11

ฉันกำลังมองหาเครื่องมือ CLI ที่จะคอยดูไดเรกทอรีและคายชื่อของไฟล์ที่เปลี่ยนแปลงตามเวลาจริง

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

ฉันรู้inotify( inotify-tools?) และดูเหมือนว่าเป็นสิ่งที่ฉันต้องการ แต่ฉันต้องการบางสิ่งที่เป็นทั้ง Linux (ในกรณีของฉัน Ubuntu) และ OSX ที่เข้ากันได้

มันไม่จำเป็นต้องเร็วนัก แต่มันก็จำเป็นที่จะต้องทำการเปลี่ยนแปลง (ภายในเสี้ยววินาทีนั้นสมเหตุสมผล) นอกจากนี้ฉันไม่จำเป็นต้องมีโปรแกรม CLI ที่แน่นอนที่กล่าวถึงข้างต้น หากเทคโนโลยีพื้นฐานบางอย่างมีอยู่และสามารถเขียนสคริปต์ได้ง่ายบนทั้งสองแพลตฟอร์มซึ่งจะยอดเยี่ยมเช่นกัน


1
ฉันชอบfswatchOS X ที่ฉันพบในคำถามที่ถูกแท็กว่าซ้ำ - superuser.com/questions/445907/ …
cwd

คำตอบ:


11

โดยทั่วไปแล้ว OS X จะใช้Folder ActionsหรือLaunchdสำหรับงานนี้

เครื่องมือข้ามแพลตฟอร์มเดียวที่ฉันรู้จักคือwatchdog APIสำหรับ Python (มีให้สำหรับ OS X และ Linux) ติดตั้งผ่านpip(หรือeasy_install)

pip install watchdog

มันมาพร้อมกับwatchmedoเครื่องมือบรรทัดคำสั่งซึ่งช่วยให้คุณสามารถรันคำสั่งเชลล์กับเหตุการณ์ของระบบ ตรวจสอบไวยากรณ์ทั่วไปด้วยwatchmedo --help

นี่คือตัวอย่างสั้น ๆ ที่คุณสามารถแก้ไขคำสั่งได้อย่างง่ายดายและเส้นทางที่ไฮไลต์เป็นตัวหนา:

watchmedo คำสั่งเชลล์ \
    - เรียกซ้ำ \
    --command = ' echo "$ {watch_src_path}" ' \
     / some / โฟลเดอร์

สิ่งนี้จะคายพา ธ ไปยังไฟล์หรือโฟลเดอร์ที่ถูกเปลี่ยนทั้งหมดทำให้คุณสามารถwatchmedoส่งออกไปยังคำสั่ง shell อื่นได้


ดูเหมือนว่าการกระทำโฟลเดอร์มีข้อ จำกัด บางอย่าง (และยากที่จะทดสอบโดยไม่ใช้ OSX) แต่watchmedoทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน ขอบคุณ!
Adrian Schneider

2

ฉันได้ปรับแต่งสคริปต์ 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!"'

ฉันหวังว่านี่จะช่วยได้! ฉันพบว่าทับทิมทำงานได้ดีมากสำหรับสิ่งนี้และติดตั้งบน OS X เป็นค่าเริ่มต้น


ให้มันยิง แต่ยากที่จะปรับแต่งโดยไม่มีพื้นหลังทับทิม ขอขอบคุณ!
Adrian Schneider

มันเยี่ยมมาก ความคิดใด ๆ ที่จะทำให้มันดูโฟลเดอร์ซ้ำด้านล่างซ้ำ?
Nate Flink

ถ้าฉันไม่สนใจเกี่ยวกับการดำเนินการของคำสั่งเกี่ยวกับการเปลี่ยนแปลงนี้จะเป็นหลายแพลตฟอร์มหรือยูนิกซ์เท่านั้น? และเป็นเวลาจริงจริงหรือ ผู้เฝ้าดูไฟล์บางรายมีความล่าช้าไร้สาระ (นาที)
Automatico

2

คุณสามารถใส่lsofลงไปในwatchคำสั่งและมีมันอัพเดททุก<s>วินาที

watch -n <s> lsof

และเรียกใช้ตัวกรองสิ่งต่าง ๆ เช่นการดู pid1, pid2, pid3 และละเว้น pid4

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

หากยังไม่พอคุณสามารถเขียนตัวกรองด้วย grep ได้ตลอดเวลา

สำหรับ OS X, เห็นนี้คำถามคำตอบ 's


0

entrเป็นสิ่งที่ดี คุณสามารถกรองไฟล์ที่แน่นอนที่คุณต้องการให้ดูเช่นนี้

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

หากคุณต้องการให้มันตรวจสอบไฟล์บางไฟล์ภายในไดเรกทอรีคุณสามารถสร้างfindคำสั่งของคุณเพื่อให้มันส่งคืนไฟล์ที่คุณต้องการดูเท่านั้น

fswatchฉันคิดว่ามันง่ายต่อการกำหนดค่ากว่า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.