Bashスクリプトのコマンドを完了するにはどうすればよいですか? (cpで切り取ったファイル)

Bashスクリプトのコマンドを完了するにはどうすればよいですか? (cpで切り取ったファイル)
  • backupname.tar.gz1時間ごとにディレクトリからファイルを受信するサーバーがあります。/home/my_user/drop

  • incronユーティリティをインストールし、/ dropに新しいファイルが表示されたら、incrontab -eエントリを使用してスクリプトを実行しました。

スクリプトは次のとおりです。

#!/bin/sh
#
# First clear the 2 immediate use directories
rm /home/my_user/local_ready/*
wait
sleep 1
rm /home/my_user/local_restore/*
wait
sleep1

# Copy the file from the /drop /local_ready
cp /home/my_user/drop/*.tar.gz /home/my_user/local_ready/
wait
sleep 5

# Now move the file to the /current folder
mv /home/my_user/drop/*.tar.gz /home/my_user/current/
wait
sleep 1

# Next we delete any stray files dropped that are not
# of the target type so we can keep /drop clean.
rm /home/my_user/drop/*
wait
sleep 1

# Un-Tar the files into the /local_restore directory
tar -xzf /home/my_user/local_ready/*.tar.gz -C /home/my_user/local_restore/
wait
sleep 1

# This should complete the movement of files

私が経験している問題は、/local_restoreスクリプト内の次のコマンドがコマンドが中断されるように、ディレクトリにコピーされたファイルが切り捨てられることですcp

最初に動作させるには、sleepコマンドを追加してから、スクリプト内の各コマンドの後にwaitコマンドを追加して動作させました。これにより、cpコマンドがファイルのコピーを完了するまですべてが待機するようになると思いました。場所。

コマンドはチェーンにファイルを正常に配置するtarコマンドに依存しているため、コマンドが機能しているかどうかはわかりません。cpいずれかのファイルを解凍するためのコマンドのみを使用して実行したテストでは、スクリプトが終了する前に完了しないことが予想されます。少なくともそれはタイミング理論をテストするために使用された別の3線テストで起こったことです。

ちなみに...mvコマンドが正常に動作し、ファイル全体が期待どおりに移動します。

スクリプト内で実行されているコマンドがタスクを完了できない理由は誰にでもわかりますか?

incrontabエントリの内容を表示するように求められたので、次のようになります。

/home/my_user/drop/ IN_CREATE /home/my_user/bin/cycle_backups

(cycle_backupsは明らかにスクリプトファイルの名前です)

Ubuntu 16.04 LTSを実行し、10GBのメモリと100GB以上のディスク容量を備えたKVMタイプのVPSクラウドサーバー。ファイルが削除されると、システムアイドルに加えてサーバーが実行する唯一の作業です。

私のサーバーが少し遅いことを認めているので、200 mbファイルを別のディレクトリにコピーしようとすると、コマンドラインで正しく実行しても完了するのに1〜2秒かかります。

問題を説明できないため、解決策を見つけるのはさらに困難です。

公正な警告:私はこの分野では最高ではありませんが、達成することは不可能なことだとは思いません。

ベストアンサー1

waitバックグラウンド操作がないため、すべての呼び出しはスクリプトで何もしません。このコンテンツは安全に削除できます。

への呼び出しも削除しますsleep。この時点では、スクリプトの実行だけが遅れます。それにもかかわらず、前のコマンドが正しく完了するまでコマンドは開始されません。sleep1「コマンドが見つかりません」エラーが発生する可能性があります。

あなたのスクリプトで見ることができる唯一の実際の問題は最後の呼び出しですtar

tar -xzf /home/my_user/local_ready/*.tar.gz -C /home/my_user/local_restore/

に複数のアーカイブがある場合、/home/my_user/local_readyこのコマンドは最初のアーカイブを抽出し、そのアーカイブから別のアーカイブの名前を抽出しようとします。この-fロゴは一つアーカイブであり、実際に複数のアーカイブを一度に抽出することはできません。

代わりにループを使用してください。

for archive in /home/my_user/local_ready/*.tar.gz; do
    tar -xzf "$archive" -C /home/my_user/local_restore/
done

私は持っています無視されるこのスクリプトがそれ自体と同時に実行されると、何が起こるのか考えてみましょう。新しいファイルが表示されたときにスクリプトを実行するためのいくつかのツールがあると述べましたが、2つ以上のファイルが同時に表示される場合、何が起こるのかは明らかではありません。スクリプトが処理中なのでみんな単一の呼び出しでファイルを転送する場合、同時に実行される2つのスクリプトが互いにつま先を踏む可能性が高いと確信しています。

個人的に、私はおそらく5分ごとにスクリプトを実行したでしょう。または、特定の種類のロックを使用して、スクリプトの他のコピーがすでに実行されている間にスクリプトが実行されないようにします("シェルスクリプトのロックは正しいですか?")。

これは私が自分で書いたコードです(どんな種類のロックも使用しません)。

#!/bin/sh -e

cd /home/my_user

# clear directories
rm -f local_ready/*
rm -f local_restore/*

# Alternatively, remove directories completely
# to also get rid of hidden files etc.:
#
#  rm -rf local_ready;   mkdir local_ready
#  rm -rf local_restore; mkdir local_restore

# handle the archives, one by one
for archive in drop/*.tar.gz; do
    tar -xzf "$archive" -C local_restore
    cp "$archive" current
    mv "$archive" local_ready
done

これにより、名前が隠されていないディレクトリが消去され、各アーカイブが抽出されます。アーカイブを抽出してディレクトリにコピーし、local_readyアーカイブdropをから移動しますcurrent

私はこれを使用sh -eしてエラーが発生したときにスクリプトを終了し、スクリプトへの長いパスを避けるためにディレクトリcdに移動します(これにより、後でタスク全体をサブディレクトリまたは他の場所に簡単に移動できます)。/home/my_user私はこれらのディレクトリを消去しましたが、rm -fglobが何も拡張されないとrm文句を言いました。*

明らかに、アーカイブのコピーと抽出を別々に処理することもできます。

cp drop/*.tar.gz current
mv drop/*.tar.gz local_ready

for archive in local_ready/*.tar.gz; do
    tar -xzf "$archive" -C local_restore
done

local_readyスペースを節約するには、次のハードリンクとファイルを確認することをお勧めしますcurrent

mv drop/*.tar.gz local_ready

for archive in local_ready/*.tar.gz; do
    ln "$archive" current
    tar -xzf "$archive" -C local_restore
done

おすすめ記事