Unix移動コマンドについて


4

csv入力ファイルを/ exp / filesフォルダから/ exp / readyディレクトリに移動するUnixシェルスクリプトtran.shを書く必要があります。

csv入力ファイルはに書き込まれます /exp/files その振る舞いを私は自明に変更することはできませんFTPサーバーによってフォルダー。に tran.sh シェルスクリプトcsv入力ファイルを/ exp / filesディレクトリから移動する前に、他のプロセスがそのファイルに書き込んでいないことを確認する必要があります。

どうしたらいいですか。


ところで - それは(任意のプロセスとは対照的に)FTPサーバーであることを知っていることは本当に適切な答えのセットを変えます。私は確かに私のものを更新する原因がありました。次回の質問でより多くの情報を提供してください。

回答:


3

移植する方法はありません。あなたが試すことができます fuserlsofinotifyFAM他の人も


いい答え、ポイントにまっすぐにカットします。私はあなたもglibとgaminを追加できると思います
Matt Joiner

3

使ってみる fuser [FILE]。ファイルが使用されていない場合は、ゼロ以外の値が返されます。

ファイルの移動準備が整うのを待つコードの例をいくつか示します。

#!/bin/sh

FROMDIR='/exp/files'
DESTDIR='/exp/ready'

function move_file_if_ready () {
    if [ -f "$1" ]; then
        while fuser "$1" 2>/dev/null 1>&2 ; do
            sleep 1
        done

        mv "$1" "$DESTDIR"
    fi
}

for "$fn" in "$FROMDIR"/*.csv; do
    move_file_if_ready "$fn"
done

1
悪くないが、それでもまだレースコンディションがある。
dmckee

どうもありがとう。 3つのリモートアプリケーションプロセスが入力ファイルをこのディレクトリにftpしています。だから私は彼らがファイルに書き込んでいるかどうか、このfuserコマンドで知ることができるでしょう。

@dmckee - 競合状態については真実ですが、書き込み処理ではファイルハンドルを書き込み可能な長さだけ開いたままにしてから閉じ、再び開かないようにしています。
amphetamachine

どうもありがとう。 csvファイル内の最後の行が受信されたかどうかを確認し、ファイルを検証することを計画しています

3

あなたはlsofを使用することができます

r=$(lsof /exp/files )
if [ ! -z "$r" ] ;then
  mv /exp/files/*csv /exp/ready
fi

どうもありがとう。 3つのリモートアプリケーションプロセスが入力ファイルをこのディレクトリにftpしています。だから私は彼らがファイルに書き込んでいるかどうか私はこのlsofコマンドで知ることができるでしょう。

しかし、3つの(独立していると仮定した)プロセスがディレクトリのファイルに書き込む場合、3つすべてが終了しない限り、これは動きません。 fuserを使用し、ファイルごとにテストする方がよりモジュール的です。
amphetamachine

どうもありがとう。 csvファイル内の最後の行が受信されたかどうかを確認し、ファイルを検証することを計画しています。

2

これを行う正しい方法は、ファイルへの書き込みを行うプロセスに、書き込みが完了したときにファイルの名前を変更するか、ファイルの名前を変更することです。それ以外のものは競合状態や許可問題になりがちです。

問題の事例のいくつかの特定の例:

  • ファイルを移動するプロセスがlsof / fuser / etcとは異なるユーザーとして実行されている場合、情報は完全であるとは保証されません。
  • 書き込みを行っているプロセスがシェルスクリプトの場合、ファイルを開くサブプロセスを起動したり、閉じたり、別のサブプロセスを起動したりすることができます。それ以上のサブプロセスが後でそれへの書き込みを開始する場合でも

他にも、もっと微妙な競合状態が存在するかもしれません - そして、それにもかかわらず、lsof、fuserなどはPOSIXツールではなく、どこでも利用できるわけではありません。

プロトコルの問題として、ファイルを書き込んでいるプロセスが、完了時にそれらを最終的な場所に移動することを要求します。それは唯一の安全で携帯可能な方法です。

編集:ファイルが任意のプロセス(それらを閉じて再び開くことがある)によってではなく、FTPサーバによって書かれていることが明らかにされています。この場合、 incron このディレクトリでファイルが閉じられたときはいつでも任意のスクリプトを実行するために使用できます。


情報をありがとう。問題は3つのリモートアプリケーションプロセスがこのディレクトリにファイルをftpしていることです。だから私は彼らがこの/ exp / filesディレクトリにそれを書いているときファイルを移動してはいけません

@arav - これを回避できます(つまり、 これを回避するには、カスタムSFTPサーバーを使用します。 (Mineは、Paramikoライブラリーを使用してPythonで書かれています。FTPを避ける理由は多数ありますが、Pythonでも標準のFTPサーバーをPythonで書くためのftpdlibがあります)。

@arav - ...そうは言っても、アップデートが完了したらいつでもinotifywatchまたはincronを使用して選択したスクリプトを実行するという、競合条件のない別の解決策のように思えます。

0

これらのファイルを作成するプロセスを変更せずにこれを実行できるとは思わない。私たちのシステムでこのようなタスクがあるときはいつでも、ファイルを作成するプロセスが最後にそれを実行可能にすることを確認します。そのため、そのようなファイルが他の方法で移動または後処理を行うプロセスは、元のプロセスがファイルの処理を完了したことを確認するために実行可能ビットをチェックできます。


問題は、3つのリモートアプリケーションプロセスがファイルをこのディレクトリにftpしていることです。だから私は3つのリモートアプリのプロセスが完了したことを確認することができます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.