Skip to content

Instantly share code, notes, and snippets.

@hyuki

hyuki/chat.md Secret

Created July 6, 2023 23:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hyuki/5943d2643a4291bbc88d96993601578e to your computer and use it in GitHub Desktop.
Save hyuki/5943d2643a4291bbc88d96993601578e to your computer and use it in GitHub Desktop.
#ChatGPT と結城浩の対話: macOSで特定のフォルダにファイルが新たに追加されたかどうかを監視するRubyスクリプトを作ってください。

Model: GPT-4

Date: 2023-07-07

macOSで特定のフォルダにファイルが新たに追加されたかどうかを監視し続け、もしも追加されたならばそのファイル名を表示するRubyスクリプトを作ってもらえますか。

macOSにはファイルシステムイベントを監視するフレームワークが含まれていますが、その機能を直接Rubyから使用することは難しいです。ですが、このようなケースのために作られた、rb-fseventというgemがあります。このgemを使用することで、簡単に指定したディレクトリの変更を監視することができます。

以下に、指定したディレクトリに新たにファイルが追加された場合にそのファイル名を表示するRubyスクリプトを示します。まずはrb-fseventをインストールしてください。

gem install rb-fsevent

次に以下のRubyスクリプトを作成してください。ここでは監視するディレクトリとして/path/to/watchを使用しています。適切なパスに書き換えて使用してください。

require 'rb-fsevent'

# 監視するディレクトリ
watch_dir = '/path/to/watch'
prev_files = Dir.glob("#{watch_dir}/**/*")

fsevent = FSEvent.new
fsevent.watch Dir.pwd do
  current_files = Dir.glob("#{watch_dir}/**/*")
  added_files = current_files - prev_files

  added_files.each do |file|
    puts "新たに追加されたファイル: #{file}"
  end

  prev_files = current_files
end
fsevent.run

上記スクリプトは、指定したディレクトリのファイルのリストを定期的に更新し、新たなファイルが追加された場合にそのファイル名を表示します。ファイルのリストは、再帰的にすべてのサブディレクトリを含んで取得します("#{watch_dir}/**/*")。

ただし、このスクリプトは新規ファイルの追加のみを検知します。ファイルの削除や変更を検知するには、さらなる処理が必要になります。

なお、実際に動作を確認するにはこのスクリプトを保存し、rubyコマンドで実行してください。

ruby watch_directory.rb

新たにファイルが追加されるとそのファイル名がターミナルに出力されます。

watch_directory.rbのDir.pwdはwatch_dirのまちがいではありませんか?

すみません、その通りです。Dir.pwdはスクリプトが実行された現在のディレクトリを返しますが、ここでは監視対象のディレクトリwatch_dirを指定するべきでした。以下に修正したコードを記載します:

require 'rb-fsevent'

# 監視するディレクトリ
watch_dir = '/path/to/watch'
prev_files = Dir.glob("#{watch_dir}/**/*")

fsevent = FSEvent.new
fsevent.watch watch_dir do
  current_files = Dir.glob("#{watch_dir}/**/*")
  added_files = current_files - prev_files

  added_files.each do |file|
    puts "新たに追加されたファイル: #{file}"
  end

  prev_files = current_files
end
fsevent.run

この修正により、スクリプトは指定したwatch_dirディレクトリの変更を監視します。新たにファイルが追加されると、そのファイル名がターミナルに出力されます。

fsevent.watch watch_dirに与えるブロックに引数がないと動かないようです。 つまり、

すみません、それは私の見落としでした。ご指摘ありがとうございます。

FSEvent.watchのブロックは実際には変更されたディレクトリのパスを引数として取ります。しかし、この場合はその引数を使用せず、単に指定ディレクトリのファイルリストを更新して新しいファイルがあるかどうかを確認します。修正されたコードは以下の通りです:

require 'rb-fsevent'

# 監視するディレクトリ
watch_dir = '/path/to/watch'
prev_files = Dir.glob("#{watch_dir}/**/*")

fsevent = FSEvent.new
fsevent.watch watch_dir do |_dirs|
  current_files = Dir.glob("#{watch_dir}/**/*")
  added_files = current_files - prev_files

  added_files.each do |file|
    puts "新たに追加されたファイル: #{file}"
  end

  prev_files = current_files
end
fsevent.run

ここでは_dirsを使用してブロックの引数を明示しましたが、この変数はこのコードでは使用されていません。アンダースコアを接頭辞として使用することは、変数が存在するが実際には使用されていないことを示す慣習的な方法です。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment