2012-03-01 4 views
6

はのように、私はいくつかのWindowsシンボリックリンクを作成するとします。perlスクリプトのWindowsシンボリックリンクを削除しますか?

rd /s /q source withlink linkdir 
mkdir source 
mkdir withlink 
echo blah > source/myfile 
cd withlink 
touch blah 
mklink mylink ..\source\myfile 
@REM mklink /d linkdir ..\source 
cd .. 

私はperlスクリプトで行うには、同じタスクを持っている

rd /s /q withlink 

とシェルでシンボリックリンクを含むディレクトリを削除することができます現在Cygwinのrm -rfを使用しています。残念ながら私たちはcygwin 1.5を使用していますが、rmとrm -rfは、使用したいシンボリックリンク上でそのバージョンで正しく動作しません(they delete symbolic link contents instead of the symlinks)。私は、その後のperlの、(上記作成-リンクを順番に出しREM'ed 1のような)任意のディレクトリのシンボリックリンクを持っていない提供

use File::Path qw(rmtree) ; 
rmtree(['withlink']) ; 

これはうまく動作します、:

私がしようとした場合rmtreeはcygwinのように動作し、元のディレクトリのディレクトリ内容が削除されてしまいます。

誰でも私が使用できる代替のperl再帰的なディレクトリ削除方法の提案をしていますか?私はシェルコールアウトを考えた:

system("rd /s /q withlink") ; 

が、これは私がプラットフォームをテストし、WindowsとUnixのためのさまざまなPerlコードを持っている必要があり。

EDIT: Unixとは違って、unlink()は少なくともビルドシステムが現在使用しているperl v5.6.0のディレクトリシンボリックリンクを削除するようには機能しません。しかし、rmdir()はWindowsディレクトリのシンボリックリンクを削除するために動作します。

+0

試してみたら....何ですか? –

+0

申し訳ありませんが、私はまだ私の質問をしている間に私のタイトルを少し編集し、不完全な状態で途中で質問を誤って提出しました。 –

+0

ありがとうございました! –

答えて

0

perlスクリプトでunlink("FILE_FOO");コールを使用する必要があります。ポータブルです。

+0

いいえ、unlinkもrmdirもディレクトリのsymlinksで正しく動作しません。私は問題の私の記述でそれを言及すべきだった。 –

+0

修正。 unlinkは、Windows上のディレクトリのシンボリックリンクでは機能しません(unixではunlinkとは異なります)。 Windowsディレクトリのシンボリックリンクにはrmdir()が必要です。 –

2

rmdirを使用してWindowsのディレクトリシンボリックリンクと接続ポイントを削除する必要があります。ファイルへのシンボリックリンクを削除するには、unlinkを使用する必要があります。その理由は、ディレクトリのシンボリックリンクと接続ポイントは実際には追加のファイルシステムメタデータ(再解析ポイントデータと呼ばれます)を持つ空のディレクトリです。同様に、ファイルへのシンボリックリンクは、の再解析点データを持つ空のファイルです。このようなディレクトリまたはファイルは、Microsoft NTFSのマニュアルを読むと再解析ポイントと呼ばれます。再解析ポイントタイプは、再解析ポイントTAGと呼ばれます。 『リンク』としてユーザーに表示さ2つの再解析ポイントのタグがあります。

  1. IO_REPARSE_TAG_SYMLINK - ディレクトリに設定されている場合 - ファイルに設定されている場合、それは、ディレクトリへのシンボリックリンクである - それはへのシンボリックリンクですファイル
  2. IO_REPARSE_TAG_MOUNT_POINT - ディレクトリにのみ設定することができます。これは「接続ポイント」と呼ばれます。別のディレクトリに "リンク"することもできますが、デバイス全体(ボリューム)の "マウントポイント"にすることもできます。

は、要約すると:

  1. あなたは、ディレクトリとの接続点にシンボリックリンクを削除し、彼らがのディレクトリであるかのように(実際には、あなたがそのようなことの属性をチェックすると、2つがありますFILE_ATTRIBUTE_DIRECTORYをしてFILE_ATTRIBUTE_REPARSE_POINT) 。
  2. ファイルへのシンボリックリンクをファイルのように削除します。
  3. 上記の両方の場合、リンク/ジャンクションのみが削除されます(ターゲットではありません)。
  4. は、ファイル/フォルダのリンク(すべての種類)があるかどうかを確認するには:あなたが、その後GetFileAttributesまたはGetFileInformationByHandleまたはFindNextFileを呼び出す場合attributtesはFILE_ATTRIBUTE_REPARSE_POINTフラグ(例えばは:WIN32_FIND_DATA::dwFileAttributes)を含有します。ディレクトリへのリンクの場合は、フラグFILE_ATTRIBUTE_DIRECTORY1.参照)も含まれています。

希望があれば。

+0

これは私が見つけたものと一貫していますが、情報に感謝します。 perl内でこれらのファイルシステムタグを照会する方法を知っていますか、またはFindFirstFile(およびフレンド)を呼び出すCコードを記述する必要がありますか? –

+0

はい、Windows XP以降で動作するこれらのリパースタグを照会/設定/削除できるC++コードがあります。コードは長すぎてここに投稿するのが複雑ですが、記事全体を書く必要があります。これは主に私の実験とMSDNの読書に基づいています。 Vistaから、 'CreateSymbolicLink'関数を使ってシンボリックリンクを作成したり、' CreateHardLink'(XP以降)を使ってハードリンクを作成することができます。私は私の答えを更新しました - リンク/ジャンクションを検出する方法 - 上記を参照してください。 – sirgeorge

関連する問題