ローカルNTFSパーティションでWindowsの違法ファイル名を防ぐためのiconvモジュール(rsyncで使用)

ローカルNTFSパーティションでWindowsの違法ファイル名を防ぐためのiconvモジュール(rsyncで使用)

NTFSボリュームを自分のUnix(Ubuntu)システムにローカルに接続し、rsyncを使用してWindowsから結果を読み取ることができるように、いくつかのUnixディレクトリをここにコピーしたいと思います。

私は所有権と権限に興味がありません。修正日を保存できればいいようです。ディレクトリとファイルのみが必要です(シンボルリンクも問題ありませんが、コピーできない場合は問題ありません)。

2つの明らかな問題は、大文字と小文字の区別とWindowsファイル名の無効な文字です。たとえば、Linuxでは「a」と「A」という2つのファイルをNTFSボリュームにコピーできますが、Windowsでは最大1つにアクセスできます。しかし、私はその問題を無視することができてうれしいです。私が興味を持っているのは、Windowsファイル名の違法文字です。 <、>、:、"、/、\、|、?、および*(実際にはASCII 0-31もありますが、気にしません。"."で終わるファイルにも問題がある可能性がありますか?

rsyncが自動的に「a:」というファイルの名前をa(COLON)に変更し、正当な名前で終わるようにしたい(理想的にはa(COLON)を再びa:に翻訳)

Windowsで禁止されている文字を避けるために、rsyncは自動的にファイル名を変更できますか?

  • 私が知る限り、rsyncを使うことができますこれらのタスクを実行するために、Windowsファイル名の標準iconvモジュールはありますか? (直接gconvモジュールをプログラムする方法を簡単に見てみましたが、Cの知識が不足して複雑すぎるようです)。
  • 私は聞いたrdiff バックアップ同様の変換を実行することは可能ですが、ホームページでは「自動的に」操作を実行すると言われており、ローカルにインストールされているNTFSボリュームが信頼できる方法で名前変更をトリガーするかどうかはわかりません。
  • 私はそこにいることを知っていますヒューズポッシソブルしかし、これは私の目的に比べて少し過剰であるように見え、よく文書化されていないようです(どの文字がどのように翻訳されますか?すべてのファイル名が8.3または他のものに切り捨てられますか? ?この情報は必要ありません。)
  • たとえば、次の方法でこれを行うことができます。アスファルトファイル;しかし、それは私が望むものではありません。 (具体的には、NTFSボリュームからWindowsの別のバックアップパーティションに追加コピーして、変更されたファイルのみをコピーしたいと思います。)
  • わかりました」ウィンドウ名「オプションを使用すると、問題のあるファイルの名前を変更するのではなく、問題のあるファイルが生成されるのを防ぎます。

修正する:私の質問はあまり明確ではないようです。もっと明確な例を見てみましょう。たとえば、WINDOWS-1251は私には適していませんでした。iconv -f utf-8 -t WINDOWS-1251//TRANSLIT 変化

123 abc ABC äö &:<!|

入力する

123 abc ABC ao &:<!|

文字列を次のように変換するwindows-filenams(存在しない)などのコードページが必要です。

123 abc ABC äö &(COLON)(LT)!(PIPE)

アップデート2:私は今放棄し、問題のあるファイルの名前を「手動で」(つまりスクリプトを介して)変更しました。これから、すべてのrsyncを実行する前に問題のあるファイル名を確認するスクリプトを実行します(ただし、名前の変更は自動的には処理されません)。

# find stuff containing forbidden chars
find $MYDIR -regex '.*/[^/]*[<>:*"\\|?][^/]*'
# find stuff containing dot as last character (supposedly bad for windows)
find $MYDIR -regex '.*\.'
# find stuff that is identical case insensitive
find $MYDIR -print0 | sort -z | uniq -diz | tr '\0' '\n'

(最後の行は重複ファイル名の大文字と小文字を区別せずに検索)

答え1

実用的な解決策は、ソースファイルへのハードリンクを使用して、目的の変換されたファイル名でソースディレクトリをローカルで再生成し、そのコピーをそのままntfsファイルシステムにrsyncすることです。

たとえば、このPerlスクリプトは、階層を不要な文字にコピーし、不要/tmp/a/な文字をURLエンコード(2つの16進数を使用)して、その文字が/tmp/b/(ハードリンク)、ディレクトリがディレクトリになる方法を示しています。%file:bfile%3ab%b<ha>%25b%3cha%3e

#!/usr/bin/perl
use strict;
use File::Find;
my $startdir = '/tmp/a';
my $copydir = '/tmp/b';
sub handlefile{
    my $name = substr($File::Find::name,1);
    my $oldname = $startdir.$name;
    $name =~ s/([;, \t+%&<>:\"\\|?*])/sprintf('%%%02x',ord($1))/ge;
    $name = $copydir.$name;
    printf "from %s to %s\n",$oldname,$name;
    if(!-l and -d){ mkdir($name) or die $!; }
    else{ link($oldname,$name) or die $!; }
}
chdir($startdir) or die;
find(\&handlefile, '.');

rsync /tmp/bその後、ntfsに移動できます。これは単なるデモであり、Unicodeやntfsの他の制限事項(最大ファイル名の長さなど)を解決する必要があります。小文字/大文字の競合を確認し、必要なエンコード(:toCOLONなど)を使用することもできます。 2番目の手順を実行して、ディレクトリのタイムスタンプを変更できます。何百万ものファイルがない限り、ファイルへのハードリンクを含むディレクトリ構造のコピーを作成するために必要な作業はあまり面倒ではありません。

関連情報