1

.binこのスクリプトを使用して、作成中の新しいファイルのダウンロード フォルダーを監視しています。ただし、機能していないようです。grep を削除すると、ダウンロード フォルダーに作成されたファイルをコピーできますが、grep では機能しません。問題は、2 つの値を比較しようとしている方法にあると思われますが、どうすればよいかわかりません。

#!/bin/sh

downloadDir="$HOME/Downloads/"
mbedDir="/media/mbed"

inotifywait -m --format %f -e create $downloadDir -q | \
while read line; do
    if [ $(ls $downloadDir -a1 | grep '[^.].*bin' | head -1) == $line ]; then
        cp "$downloadDir/$line" "$mbedDir/$line"
    fi
done
4

1 に答える 1

2

これls $downloadDir -a1 | grep '[^.].*bin' | head -1は間違った方法です。理由を確認するために、ダウンロード ディレクトリに と という名前のファイルがあり、それa.txtが追加されたとします。を出力し、(\n ではなく実際の改行を使用して)を出力し、それを に細くし、最初の行以外をすべて削除して を残し、これは と一致しません。ディレクトリリストをスキャンするのではなく、 で終わるかどうかを確認する必要があります。これを行うには、次の 3 つの方法を紹介します。b.binc.bininotifywaitc.binlsa.txt\nb.bin\nc.bingrepb.bin\nc.binheadb.binc.bin$line.bin

最初のオプション$lineは、リストではなくgrep を使用してチェックします。

if echo "$line" | grep -q '[.]bin$'; then

-qオプションを使用してgrepの出力を抑制していることに注意してください。代わりに、ifコマンドに終了ステータスをチェックさせているだけです(一致が見つかった場合は成功、そうでない場合は失敗)。また、RE は行末に固定され、ピリオドは括弧内にあるため、実際のピリオドのみに一致します (通常、.正規表現では任意の 1 文字に一致します)。 \.bin$ここでも機能します。

2 番目のオプションは、変数の内容を編集するシェルの機能を使用して、で$line終わるかどうかを確認し.binます。

if [ "${line%.bin}" != "$line" ]; then

その部分は、そこにある場合、最後からトリミングされた"${line%.bin}"$line の値を示します。それがそれ自体.binと同じでない場合は、 で終わっている必要があります。$line$line.bin

3 番目のオプションでは、bash の[[ ]]式を使用してパターン マッチングを直接実行します。

if [[ "$line" == *.bin ]]; then

これは (IMHO) 最もシンプルで明確ですが、bash でのみ機能します (つまり、スクリプトを で開始する必要があります#!/bin/bash)。

その他の注意: ファイル名の空白とバックスラッシュに関する問題を回避するために、while IFS= read -r line; do二重引用符に関する @shellter の推奨事項を厳密に使用し、それに従ってください。

また、私は inotifywait にはあまり詳しくありませんが、AIUI の-e createオプションは、ファイルの内容が完全に書き出されたときではなく、ファイルが作成されたときに通知します。タイミングによっては、部分的に書き込まれたファイルをコピーしてしまう可能性があります。

最後に、重複したファイル名のチェックはありません。foo.binという名前のファイルをダウンロードし、それがコピーされ、元のファイルを削除してから、という名前の別のファイルをダウンロードするとどうなるでしょうかfoo.bin。スクリプトが現在のように、最初のfoo.bin. これが望ましくない場合は、次のようなものを追加する必要があります。

if [ ! -e "$mbedDir/$line" ]; then
    cp "$downloadDir/$line" "$mbedDir/$line"
elif ! cmp -s "$downloadDir/$line" "$mbedDir/$line"; then
    echo "Eeek, a duplicate filename!" >&2
    # or possibly something more constructive than that...
fi
于 2011-11-17T20:43:51.700 に答える