ディレクトリを監視し、リアルタイムで変更されるファイルの名前を出力する CLI ツールを探しています。
some_watch_command /path/to/some/folder | xargs some_callback
私はinotify
( inotify-tools
?) を認識しており、それが必要なものであるように思われますが、Linux (私の場合は Ubuntu) と OSX の両方と互換性のあるものが必要です。
超高速である必要はありませんが、変更時にトリガーする必要があります (1 秒以内が妥当です)。また、上記の CLI プログラムそのものが必ずしも必要というわけではありません。基盤となるテクノロジが存在し、両方のプラットフォームで簡単にスクリプト化できる場合は、それも素晴らしいことです。
答え1
OS Xは通常フォルダーアクションまたは起動このタスクのために。
私が知っている唯一のクロスプラットフォームツールはウォッチドッグ APIPython用(OS XとLinuxで利用可能)。pip
(またはeasy_install
)からインストールします。
pip install watchdog
コマンドラインツールが付属しておりwatchmedo
、システムイベントでシェルコマンドを実行できます。一般的な構文は以下で確認できます。watchmedo --help
以下は、太字で強調表示されているコマンドとパスを簡単に変更できる短い例です。
watchmedo シェルコマンド \ --再帰\ --コマンド='echo "${watch_src_path}"'\ /some/フォルダ
これにより、変更されたすべてのファイルまたはフォルダーへのパスが単純に吐き出され、watchmedo
の出力を別のシェル コマンドにパイプできるようになります。
答え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 コードの 2 つのパラメータを取ります。たとえば、
ruby OnSaveFolder.rb '/home/Movies' 'echo "A movie has been changed!"'
これが役に立つことを願っています。Ruby はこの種の用途に非常に適しており、OS X にはデフォルトでインストールされていることがわかりました。
答え3
lsof
コマンドを入力してwatch
、1 秒ごとに更新することもできます<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
。