この見えないファイルをどのように削除できますか?

この見えないファイルをどのように削除できますか?

背景

というフォルダがありますakorg✽。このUnicode文字は、ソフトウェアが私のファイルパスのテキストエンコーディングについて間違った仮定をしたときに面倒なことになるので、名前からそれらを削除したいと思います。

質問

これは簡単だと思うかもしれません:

$ mv akorg✽ akorg
mv: cannot move ‘akorg✽’ to a subdirectory of itself, ‘akorg/akorg✽’

しかし、これは奇妙です。名前付きフォルダがakorg既に存在すると思います。私は一つもないと確信しています。

$ ls -la
total 699K
drwxr-xr-x 15 ak ak   15 Jun 12 17:34 .
drwxr-xr-x 57 ak ak 4.0K Jun 12 17:35 ..
drwxr-xr-x 11 ak ak   21 Jun 12 16:58 akorg✽
drwxr-xr-x  2 ak ak    2 May 28 20:47 Desktop
...

ところでstatまたこういう言葉があります。

$ stat akorg
  File: ‘akorg’
  Size: 21          Blocks: 33         IO Block: 1536   directory
Device: 15h/21d Inode: 292128      Links: 11
...

明らかに見えないフォルダがあるようです。とにかく削除します。

$ rmdir akorg
rmdir: failed to remove ‘akorg’: No such file or directory

それでは。一体これは何ですか?

私が今まで知っていること

  • 使っています安定したリリース~のLinuxのZFS。これはzpoolステータスとzfsプロパティ
  • statakorgそしてすべてに対して同じinodeを返しますakorg✽。このインデックスノードで検索すると、次の値のみが返されますakorg✽

    $ find . -maxdepth 1 -inum 292128
    ./akorg✽
    
  • 「見えない」フォルダでは機能しない追加の操作:

    $ rm akorg
    rm: cannot remove ‘akorg’: Is a directory
    $ unlink akorg
    unlink: cannot unlink ‘akorg’: Is a directory
    $ mv akorg akorg_temp
    mv: cannot move ‘akorg’ to ‘akorg_temp’: No such file or directory
    
  • Bash 4.2.45とzsh 5.0.0で同じ結果が得られました。どちらの場合も、タブの完成akのみが返されますakorg✽/
  • これストレス最初の名前を変更しようとすると、名前を正しく入力したことが確認され、名前が既存のフォルダによってブロックされましたakorg
  • より明示的な名前変更の試みへの応答は複雑で恐ろしいものでした。

    $ mv --verbose --no-target-directory --no-clobber akorg✽ akorg
    removed ‘akorg✽’
    

    なぜ削除したと主張するのかakorg✽、なぜ試すのか理解できません。幸い、実際には何も消えていないことがわかりlsましstat akorg akorg✽た。これはストレス

  • akorg✽奇妙なエンコーディングを排除するために、今は中間名を指定しました。

    $ mv --verbose --no-target-directory --no-clobber akorg✽ bananas
    ‘akorg✽’ -> ‘bananas’
    

    予想通り、

    $ ls -la
    total 715K
    drwxr-xr-x 16 ak ak   16 Jun 13 15:11 .
    drwxr-xr-x 57 ak ak 4.0K Jun 13 14:03 ..
    drwxr-xr-x 11 ak ak   21 Jun 12 16:58 bananas
    drwxr-xr-x  2 ak ak    2 May 28 20:47 Desktop
    ...
    

    ただし、「invisible」フォルダはまだ存在します。

    $ stat bananas akorg
      File: ‘bananas’
      Size: 21          Blocks: 33         IO Block: 1536   directory
    Device: 15h/21d Inode: 292128      Links: 11
    ...
      File: ‘akorg’
      Size: 21          Blocks: 33         IO Block: 1536   directory
    Device: 15h/21d Inode: 292128      Links: 11
    ...
    

    mvその名前を使用しようとすると、まだ奇妙に動作しますakorg

    $ mv --verbose --no-target-directory --no-clobber bananas akorg
    removed ‘bananas’
    

答え1

zshを使用している場合は、タブ補完またはシェルワイルドカードを使用することをお勧めします(削除する前に常にecho / lsを使用)。それでも問題が解決しない場合は、次のようないくつかのオプションがあります。

Hex Dumpでファイル名を確認して$'...'入力するために使用します。

% touch akorg✽   
% ls | grep akorg | hexdump -C
00000000  61 6b 6f 72 67 e2 9c bd  0a                       |akorg....|
00000009
% ls $'akorg\xe2\x9c\xbd'  
akorg✽
% rm $'akorg\xe2\x9c\xbd'
% ls
% 

上記の最後の文字は0a入力の末尾にある改行文字なので、名前に表示したくありません。

ls -iinode番号を取得して削除するために使用されますfind

% touch akorg✽
% ls -i
6128574 akorg✽
% find . -inum 6128574
akorg✽
% find . -inum 6128574 -delete
% ls
% 

名前で行くこともできますfind(どちらか先に印刷してください!)。

エスケープされた名前を取得してls -b入力します$'...'(印刷されていない文字に対しては機能しますが、Unicode文字には影響しないようです。他の人が参照する目的でのみ使用します)。

% ls
foo?bar
% ls -b         
foo\rbar
% rm foo$'\r'bar
% ls
% 

答え2

これはとても奇妙です。(この「答え」はコメントで始まりました;)それから少し長くなりました。 )

strace隠された文字や同様のものがないことを確認してください。それ以外の場合は、次のように表示されます(すべてが正しく機能している場合は結果を表示する必要があります)-1 ENOENT0

stat("akorg", {st_mode=S_IFDIR|0755, st_size=21, ...}) = 0

次のようにします。

lstat("akorg\342\234\275", {st_mode=S_IFDIR|0755, st_size=21, ...}) = 0

一人がメール交換をしました。反対の質問lsファイルを一覧表示しますがstat提供されますENOENT。 FreeBSDにもかかわらず。

よく理解していませんがzfs、一部の同期、スナップショットなどが失敗して破損したファイルテーブルが残る可能性がありますか?akorg試みる前に削除したディレクトリを作成したか、持っていますかmv

次の方法でエラーの説明が得られるかどうかはわかりません。

# zpool status -v

試すことができる1つは、リバースinodeルックアップをチェックし(オプションで別のエントリを追加d)、次のことを確認することですpath

# zdb -dddd <pool-name> <inode>

フォルダ名baz:

# zdb -dddd qqq 31
Object  lvl   iblk   dblk  dsize  lsize   %full  type
    31    1    16K    512     1K    512  100.00  ZFS directory
                                    264   bonus  ZFS znode
dnode flags: USED_BYTES USERUSED_ACCOUNTED 
dnode maxblkid: 0
path    /baz
uid     1000
gid     1000
atime   Fri Jun 14 12:39:46 2013
mtime   Fri Jun 14 11:55:33 2013
ctime   Fri Jun 14 11:55:33 2013
crtime  Fri Jun 14 11:55:33 2013
gen 1510
mode    40775
size    2
parent  3
links   2
xattr   0
rdev    0x0000000000000000
microzap: 512 bytes, 0 entries

foo名前付きサブディレクトリを含む、名前付きディレクトリ内に複数のサブディレクトリが含まれていますakorg✽

Object  lvl   iblk   dblk  dsize  lsize   %full  type
    16    1    16K    512     1K    512  100.00  ZFS directory
                                    264   bonus  ZFS znode
dnode flags: USED_BYTES USERUSED_ACCOUNTED 
dnode maxblkid: 0
path    /foo
uid     1000
gid     1000
atime   Fri Jun 14 13:10:38 2013
mtime   Fri Jun 14 12:13:18 2013
ctime   Fri Jun 14 12:13:18 2013
crtime  Fri Jun 14 11:41:53 2013
gen 1482
mode    40775
size    6
parent  3
links   6
xattr   0
rdev    0x0000000000000000
microzap: 512 bytes, 4 entries

    foo1 = 15 (type: Directory)
    foo2 = 18 (type: Directory)
    foo = 19 (type: Directory)
    akorg✽ = 30 (type: Directory)

さまざまな名前モードの設定もzfs get all storage/home-ak-annex(わかる限り)正常に見え、他のプロパティも読んだように見えます。ZFS プロパティ:

storage/home-ak-annex  utf8only              off                    -
storage/home-ak-annex  normalization         none                   -
storage/home-ak-annex  casesensitivity       sensitive              -

zfs自分でビルドする場合は、デバッグを有効にして./configure --enable-debug上記の-vvvv内容-bbbbなどを使用できます。

最後に新しい質問子供に。

答え3

見えないディレクトリがなく、代わりにstatファイル名が良い akorg画面に表示されるとき。

2つの可能な解決策:

  1. タブ補完機能付きのシェル(zshまたはbash)を使用してください。プロンプトに従って下さい: rm -rf akorg<tab>。 Zshは少なくともファイル名を完成させ、必要に応じてシェル特殊文字をエスケープします。

  2. 少し危険な一行:rm -rf akorg?

たとえば、次のように#2を手動で実行できますls -1 > filenames。 「filenames」というファイルには、一部のテキストエディタを使用して、問題のディレクトリを除くすべての行を削除します。rm -rf行にプレフィックスを追加します。エディタを終了します。シェルスクリプトとして実行されます。sh filenames

関連情報