我正在尋找一個 CLI 工具,它可以監視目錄並吐出即時更改的檔案名稱。
some_watch_command /path/to/some/folder | xargs some_callback
我知道inotify
(inotify-tools
?),它似乎是我所需要的,但我需要一些既兼容 Linux(在我的例子中是 Ubuntu)又兼容 OSX 的東西。
它不需要快如閃電,但確實需要在變化時觸發(一秒鐘內是合理的)。另外,我不一定需要上面提到的確切的 CLI 程序。如果存在一些底層技術並且可以在兩個平台上輕鬆編寫腳本,那就太好了。
答案1
OS X 通常會使用資料夾操作或者推出為了這個任務。
我所知道的唯一跨平台工具是看門狗API適用於 Python(因此可用於 OS X 和 Linux)。透過pip
(或easy_install
)安裝
pip install watchdog
它附帶了watchmedo
命令列工具,可讓您對系統事件執行 shell 命令。檢查其一般語法watchmedo --help
這是一個簡短的範例,您可以輕鬆修改命令和以粗體突出顯示的路徑:
watchmedo shell 指令 \ --遞迴\ --命令='回顯“${watch_src_path}”'\ /一些/資料夾
這只會輸出所有已更改檔案或資料夾的路徑,讓您可以將watchmedo
的輸出透過管道傳輸到另一個 shell 命令。
答案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 上。
答案3
您可以lsof
輸入watch
命令並讓它每秒更新一次<s>
:
watch -n <s> lsof
並使用任何過濾器啟動它,例如監視 pid1、pid2、pid3 並忽略 pid4
lsof -p "pid1,pid2,pid3,^pid4"
如果這還不夠,您可以隨時使用 grep 編寫自己的過濾器。
對於 OS X,請參閱此問題的答案。
答案4
進入很好。您可以過濾您想要它觀看的確切文件,如下所示。
find . -name '*.py' | entr python runTests.py
如果您希望它僅監視目錄中的某些文件,您可以編寫命令find
,使其僅返回您想要監視的文件。
我發現配置比fswatch
.