フォルダ(/shares/Photos)を表示するためにinotifywaitを使用しようとしていますが、そのフォルダに追加されたjpgが検出された場合は、サブディレクトリ($ small_dir)でサイズを変更する必要があります。写真マネージャの下には多くのjpgサブフォルダがあります。
木はこんな感じです。
shares
-Photos
-Folder 1
-Folder 2
.
.
.
既定では、誰かが画像をコピーするたびにfolder 1
新しいサブフォルダを作成し、画像のサイズを変更し、小さいバージョンをそのフォルダに配置する必要があります。
その後、ツリーは次のようになります。
shares
-Photos
-Folder 1
-Resized
-Folder 2
.
.
.
これまで私のコードは次のようになります。
inotifywait -mr --timefmt '%m/%d/%y %H:%M' --format '%T %w %f' -e close_write /shares/Photos --includei "\.jpg|\.jpeg" |
while read -r date time dir file; do
changed_abs=${dir}${file}
small_dir=${dir}${target}/
printf "\nFile $changed_abs was changed or created\n dir=$dir \n file=$file \n small_dir=$small_dir \n"
# Check if the $small_directory exists, if not create it.
if [ -d "$small_dir" -a ! -h "$small_dir" ]
then
echo "$small_dir found, nothing to do."
else
echo "Creating $small_dir"
mkdir $small_dir
chmod 777 $small_dir
fi
# Check to see if the file is in $small_dir, if it is, do nothing.
if [ "$dir" = "$small_dir" ]; then
printf "\nFile is in the $small_dir folder, nothing to do\n"
else
printf "\nResizing file into the $small_dir folder\n"
# Code to resize the image goes here.
fi
done
Photos
デフォルトでは動作しますが、スクリプトの実行中に新しいサブフォルダを作成すると、inotifywaitがこれを無視して何もしないという壁にぶつかりました。
close_write
と交換してみましたが、create
あまり違いはありませんでした。
どんなアドバイスや助けにも感謝します。
答え1
OPは以下を使用しています。
inotifywait -mr --timefmt '%m/%d/%y %H:%M' --format '%T %w %f' -e close_write /shares/Photos --includei "\.jpg|\.jpeg" |
関連文書--includei
言った(太い強調私):
--includei <pattern>
イベント処理名前付きPOSIX正規表現と一致するファイルのサブセットにのみ適用され、大文字と小文字を区別しません。
これは「表示イベント」ではなく「イベント処理」です。実際には、名前に含めるか処理する.jpg
ディレクトリのイベントのみを意味します。.jpeg
発生したがフィルタと一致しないディレクトリ生成イベントは処理されないため、inotifywait
呼び出されません。inotify_add_watch(2)
今回の事件とそれ以降に起こったすべてのことについて。したがって、このサブディレクトリではイベントは監視されません。
--includei
「この正規表現に対してのみイベントを処理します。または任意のディレクトリに」。
修正する:提案されたソリューション
したがって、機能させる方法は、コマンドの外部をフィルタリングする必要があるようです。grep
ttyでない場合、GNUは出力をバッファリングするので--line-buffered
。
これはユーザー入力(ファイル名のスペースなど)の影響を受けます。これを軽減するには、/
ディレクトリとファイル名の間に区切り文字を使用する必要があります(ファイル名には影響しません)。ディレクトリ部分には便利な末尾が含まれているので、/
フォーマット文字列からスペースを削除するだけで十分です(たとえば、追加の変数の処理や再利用も可能ですchanged_abs
)。これまでファイル名のフィルタリング意図を修正しています終わり文字列がjpg
あるかjpeg
、含むこれらの文字列を含み、内部にスペースがあるディレクトリの初期処理を改善することができます(changed_abs
影響を与えますが、small_dir
後で修正する必要がある方が多い)。 OPは実際にはスクリプト内のすべての関連変数を引用符で囲む必要があります({ }
引用符を変更せずに)。
変える:
inotifywait -mr --timefmt '%m/%d/%y %H:%M' --format '%T %w %f' -e close_write /shares/Photos --includei "\.jpg|\.jpeg" | while read -r date time dir file; do changed_abs=${dir}${file} small_dir=${dir}${target}/
そして:
inotifywait -mr --timefmt '%m/%d/%y %H:%M' --format '%T %w%f' -e close_write /shares/Photos |
grep --line-buffered -Ei '/[^/]*\.(jpg|jpeg)$' |
while read -r date time changed_abs; do
[ -d "$changed_abs" ] && continue # a directory looking like a picture filename was written to: skip this event
dir="${changed_abs%/*}/"
file="${changed_abs##*/}"
small_dir="${dir}${target}/"
まだ完全にテストされていませんが、これはアイデアです。ディレクトリテストが必要かどうかはわかりませんが(イベントが発生していないように見えますclose_write
)、問題にはなりません。
ノート
明確でない場合は、検出された各ディレクトリ生成イベントに対してアクション()を実行する必要が
inotify_add_watch(2)
あります。inotifywait
inotifywait
できるだけ早く次のイベント(競合条件)がない可能性があるため、このディレクトリに新しい調査を追加してください。でも録音されています。間違い部分:再帰ディレクトリに競合状態があり、観察されたコード[...]が変更されない可能性があります。
最新バージョンは、
inotifywait
最小カーネル 5.9 以降で root (または十分な特権を持っている) として実行する場合は、次のものを使用できる必要があります。fanotify(7)
inotifywait
機能はサポートされていますが、十分に新しいカーネルをサポートする必要がありますが、私のバージョンではそれを使用することはできませんでした。私が使用するシステムでfanotify(7)
この--filesystem
オプションを組み合わせると、新しいディレクトリごとにこれを行う必要がなくなり、OPのアプローチがフィルタリングに基づいて機能するようになると仮定します--includei
。