フォルダーを同時に移動して再作成するにはどうすればよいですか?


9

私は、statisticsデータファイルが定期的に格納されるUbuntuサーバーで呼び出されるフォルダーを持っています。新しいファイルを保存するために使用できるようにフォルダを再作成statisticsbackup-xxながら、フォルダの名前を変更するにはどうすればよいstatisticsですか?

statisticsフォルダ内のファイルはPHPによって作成されますfile_put_contents

フォルダーには多数のファイルがあるため、フォルダーの名前を変更することをお勧めしstatisticsます。


最初は、「同時に」とは、操作が「アトミック」(可能な限り)である必要があることを意味すると思っていました。
phk 2017

@phkはい、それはまさに私が意図したものです。
Googlebot 2017

ちなみに、正しい用語は「ディレクトリ」であり、「フォルダ」ではありません。
BerkÖzbalcı2017

回答:


7
mv statistics backup-xx && mkdir statistics

これにより、既存のstatisticsディレクトリの名前がに変更されbackup-xx、それが成功すると、新しいstatisticsディレクトリの作成が続行されます。

よりアトミックな操作については、ディレクトリを作成することを検討してくださいstatistics-001(または、類似の、おそらく001適切な形式の今日の日付に置き換えることにより)statistics

mkdir statistics-001
ln -s statistics-001 statistics

新しいデータがクリーンなディレクトリに入るようにこれを「ローテーション」する場合は、最初にディレクトリを作成してstatisticsから、そのリンクを再作成します。

mkdir statistics-002
ln -sf statistics-002 statistics

mv statistics-001 backup-001

このように任意のプログラムの書き込みstatisticsディレクトリん(このシンボリックリンクが指すがあること、すなわちディレクトリ)1それを見つけることに失敗しません。

statistics指すディレクトリに特別な権限または所有権を設定する必要がある場合は、リンクを(再)作成する前にこれらを設定してください。

1 むしろ、このようにして、プログラムが有効なターゲットディレクトリなしになる時間は、標準のUnixツールを使用して、可能な限り最小限に抑えられます。


1
chown --reference=backup-xx statistics ; chmod --reference=backup-xx statistics所有権と権限を設定することもできます。理想的には、名前を変更する前にこれを行うので、mkdir new ; chown ; chmod ; mv stats backup ; mv new statsタイププロセスです。
スティーブンハリス

@StephenHarrisはい、これらのフラグを持つシステムでは。
Kusalananda

ただし、これはアトミックではありません。それはアトミックに近いですが、かなりではありません。
CVn 2017

@MichaelKjörling修正しました。
クサラナンダ

ln -sfアトミックではありません。古いシンボリックリンクをリンク解除してから新しいシンボリックリンクを作成するように指定されていますが、これはアトミックではありません。代わりに、追加の一時シンボリックリンクを作成し、renamemvたとえばコマンドを介して)関数を使用して、古いシンボリックリンクをアトミックに置き換える必要があります。ここに私のアプローチを参照してください。git.musl-libc.org/cgit/musl/tree/tools/...
R .. GitHubのSTOP手助けICE

12

ディレクトリを別のディレクトリにアトミックに置き換える方法はありません。古いディレクトリを移動してから、新しいディレクトリを作成できます。

mv statistics backup-xx
mkdir statistics

しかし、これにより、statistics存在しない短い時間枠が残ります。これは、一部のプロセスがいつでもディレクトリにファイルをドロップする可能性がある場合の問題です。

ディレクトリを効果的にアトミックに置き換えるには、シンボリックリンクを使用する必要があります。名前に最初からの期間が含まれるディレクトリを作成します。

mkdir "statistics-$(date +%Y%m%d)"

(または、ディレクトリの命名規則を選択したい場合)。現在の場所への固定名のシンボリックリンクを作成します。

ln -s  statistics

ディレクトリを置き換えるには、まず新しいディレクトリと新しいシンボリックリンクを作成してから、それを移動して古いシンボリックリンクを上書きします。mvシンボリックリンクのプレーンもプレーンln -sもこれを実行しないことに注意してください。ターゲットディレクトリ内にエントリが作成されます。GNU coreutils ln -snfは、新しいシンボリックリンクを作成する前に既存のシンボリックリンクを削除し、パスが存在しない小さな時間枠を残すため、どちらにも適していません。mv -T新しいシンボリックリンクでGNU coreutilsを使用できます。

new_dir="statistics-$(date +%Y%m%d)"
mkdir "$new_dir"
ln -s statistics.new
mv -Tf statistics.new statistics

busybox' ln -sfもアトミックではないので、実装はわかりません。
2017

1
phkのコメントの横にあるシンボリックリンクも100%安全ではありません。実行中のプロセスがオープンディレクトリファイル記述子(シンボリックリンクターゲット)をまだ持っている可能性があり、名前が変更されたディレクトリにさらに新しいファイルを作成する可能性があります(openat()またはCWD と考えてください)。ディレクトリの内容を新しいものに移動するだけです。それは開いているファイルに関してはまだ安全ではありませんが、少し良いです。疑わしい場合は、logrotateそのような問題を可能な限り尊重する必要がある使用。
rudimeier 2017

1
@phk symlinkシステムコールは既存のファイルを上書きしないので、残念ながらシンボリックリンクを直接アトミックに切り替えることは不可能です。renameシステムコールは、既存のファイルを上書きしますが、うるさくシェルでそれを行うにはポータブルな方法はありません。-Tオプションのおかげで、GNU coreutilsでそれが可能です。
Gilles「SO-邪悪なことをやめなさい」

3

ディレクトリの名前を変更しないでください。多くのファイルがあるので、ディレクトリの名前を変更する方がよいとおっしゃっていました。これが必要だと私が考えることができる唯一の理由は、ファイルのコピーに時間がかかりすぎるためです。ただし、ファイルが同じファイルシステム上の場所に移動されている限り、ファイルの移動(名前の変更)は瞬時に行われます。ファイルシステムを変更する場合、ディレクトリまたはその内容を移動するかどうかに関係mvなく、時間がかかるため、これはあなたがすべきことだと思いますcp

だから、ただやる:

mkdir backup-xx && mv statistics/* backup-xx

隠しファイルも取得する必要がある場合は、次の操作を実行できます。

mkdir backup-xx && mv statistics/* statistics/.* backup-xx

または、使用する場合bash

shopt -s dotglob; mkdir backup-xx && mv statistics/* statistics/.* backup-xx

このようにして、ディレクトリは常にそこにありますが、その内容はシンプルで高速な操作で移動できます。


1

フォルダー自体を移動するのではなく、統計フォルダーの内容を新しく作成したディレクトリに移動できます。フォルダー全体を移動する場合は、別のコマンドを実行してディレクトリのアクセス許可を変更する必要があります。

mkdir -p <path>/backup-xxx
mv statistics/* <path>/backup-xxx/.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.