5

I've come across a file created accidentally, and having a really screwed up filename. The output of ls -lq:

ls -lq
total 2
-rw-r--r--. 1 mbyx7ag2 zk01 0 May  1  2014 ???E@X?p@8?@

I have made numerous attempts to kill this thing, but so far to no avail. Every time I get errors because the file doesn't exist, despite ls showing it there, and being able to stat it:

stat ^A?E\@X?p\@8^H\@ 
  File: `\001\360\265E@X\342p@8\b@'
  Size: 0           Blocks: 3          IO Block: 32768  regular empty file
Device: 1ah/26d Inode: 5239755888  Links: 1
Access: (0644/-rw-r--r--)  Uid: (231058/mbyx7ag2)   Gid: (10027/    zk01)
Access: 2014-05-01 15:47:28.638919596 +0100
Modify: 2014-05-01 15:47:28.638919596 +0100
Change: 2014-05-01 15:47:28.638919596 +0100

Interestingly, the stat command there is the result of tab completion, and looks nothing like the names used anywhere else.

I've tried the ideas in these questions:

How can I delete a file with no name

Is there a way to find files containing only non-printing characters?

I also tried the two methods from Removing Non-printing Characters from File Names - Arctic Region Supercomputing Centre (under "Extirpating non-printing characters").

The worrying thing is that the supposedly 'foolproof' trick of using inodes like this:

ls -i
5239755888 ???E@X?p@8?@
find . -inum 5239755888 -delete
find: cannot delete `./\001\360\265E@X\342p@8\b@': No such file or directory

doesn't work.

Does anyone know any other tricks I could use to get rid of this file?

Theolodus
  • 159

7 Answers7

5

What you stat prints seems to be the correct file name (as stored in the directory).

  File: `\001\360\265E@X\342p@8\b@'

You could build back the name (in bytes) from that with:

$ printf '%b' '\001\360\265E@X\342p@8\b@' | od -An -tx1
soh   p   5   E   @   X   b   p   @   8  bs   @
 01  f0  b5  45  40  58  e2  70  40  38  08  40

As you can see, the string starts with a control character (soh) or hexadecimal 0x01 (Octal \001). That has both bad effects (the file is dificult to erase) and good effects (it is very unlikely that a file with the same name exists in the directory).

After you move all (other) files out of the directory (to be on the safe side).

You could try to erase the file by typing rm, then the first character (soh) of the file and an asterisk (*) (similar as when you do erase a*). The trick to type the 0x01 is to type both Ctrl and v, release them and type both Ctrl and A (no need for shift). An ^A should appear on the cursor position. Then type an asterisk *. You should see this line on your console:

rm ^A*

Then press enter, and, if it works, the file should be gone.

If this doesn't work (try a couple of times), there is always the nuke solution. Move and erase all other files, change to the parent directory and then do:

rm -rf ./CorrectDirectory        ### Be careful this will erase ANYthing.

The whole directory (including the file) will be gone.

3

As you know the actual characters that are in the name, you just need to build the correct escape sequence for the file name, as explained in http://tldp.org/LDP/abs/html/escapingsection.html

  1. Creation

    $ echo test > $'\001\360\265E@X\342p@8\b@'
    $ stat $'\001\360\265E@X\342p@8\b@'
      Fichier : ''$'\001\360\265''E@X'$'\342''p@8'$'\b''@'
       Taille : 5           Blocs : 8          Blocs d'E/S : 4096       fichier
    Périphérique : 10302h/66306d    Inœud : 6948089     Liens : 1
    Accès : (0640/-rw-r-----)  UID : ( 1001/username)   GID : (                                 1003/jrousseau)
    Accès : 2018-06-20 11:40:44.333208199 +0200
    Modif. : 2018-06-20 11:40:47.589113454 +0200
    Changt : 2018-06-20 11:40:47.589113454 +0200
      Créé : -
    
  2. Deletion

    $ rm -i $'\001\360\265E@X\342p@8\b@'
    rm : supprimer fichier ''$'\001\360\265''E@X'$'\342''p@8'$'\b''@' ? y
    $
    
JRo
  • 31
  • You will notice that the user is able to stat the filename. There is therefore no issue forming the actual filename. – Kusalananda Jun 20 '18 at 10:11
  • Reading the question and all answers, I notice that nobody knows about how actually forming the filename with the correct escape sequence. – JRo Jun 21 '18 at 12:19
  • Well, the user must be able to, otherwise they would not have been able to run stat on the file. Or they may be using the inode number, obviously. – Kusalananda Jun 21 '18 at 12:23
  • Nope. As you can see, he is asking, so he is obvisouly not able to do it. Look closer at his stat command: he started with ^A, so the other chars could have come with autocompletion. He didn't typed a real question mark... So he used a trick to stat the file that he couldn't use for rm – JRo Jun 21 '18 at 12:30
0

One easy way is to use a file manager like mc. This way you can just point on the file and ask to delete it without having to think about escaping you characters.

In your case stat is able to see your file, but rm is not. That is strange. This might indeed be a problem with your file system. (try fsck.)

For more debugging you can also try to use strace to check why the one command is able to see the file, while the other is not.

Another idea would be using rm -r to delete the whole directory. (Possibly after backing up any important files inside.)

michas
  • 21,510
0

I had similar problem with file named '?'

-rw-rw-r-- 1 user user     0 Jun  2 14:41 ?

Stat shows:

  File: `\001'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 3538984     Links: 1
Access: (0664/-rw-rw-r--)  Uid: (  502/ user)   Gid: (  100/ user)
Access: 2016-06-02 14:41:38.997378769 +0200
Modify: 2016-06-02 14:41:38.997378769 +0200
Change: 2016-06-02 14:41:38.997378769 +0200

but rm '?' , or rm "?", or rm \001 did not work:

rm: cannot remove `?': No such file or directory

However, when I put the path in front of the file name, then it worked:

user@machine$ rm ./?
rm: remove regular empty file `./\001'? y

HTH

countermode
  • 7,533
  • 5
  • 31
  • 58
Michal
  • 11
0
  • list all the files in the directory and save the names to file_list
  • edit file_list removing all but those files to remove

for f in \`cat file_list\` 
do
   /bin/rm  -i  $f   # option i to be extra safe 
done 
  • 1
    Doesn't work at all with backslashed backticks; if you fix that it doesn't work for all filenames containing whitespace and many filenames containing glob chars, both of which are fairly rare in normal use but likely common in the 'screwed up filename' case of this Q. – dave_thompson_085 Mar 14 '17 at 17:23
0

In my case I got funny filenames like this one:

ls -l
-rw-rw-r--  1 user user       0 oct  3 00:13 ''$'\345''@'$'\340\300\345''P'$'\347\340\345'

Basically, it's the same "type" of funny filename as yours. It's just another representation.

Prepending a path and tabbing leads to:

ls -l ./
�@���P���

Notice, there are nine chars in this filename.

Each non-printable character starts w/ '$' and ends with a '. So, '$' is the escape sequence, followed by one or more non-printable chars and ended by '.

The whole of it itself is enclosed by '.

stat tells us:

  File: �@���P���
  Size: 0              Blocks: 0          EA Block: 4096   regular empty file
Device: fd01h/64769d     Inode: 13631791    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/user)   Gid: ( 1001/user)
Access: 2018-10-03 00:13:20.799957386 +0200
Modify: 2018-10-03 00:13:20.799957386 +0200
Change: 2018-10-03 00:13:20.799957386 +0200
 Birth: -

We can delete this file w/:

rm ./?@*

To finally answer your question, you should be able to remove your file using i.e.:

rm ./???E@*

cheers

Gen.Stack
  • 790
  • It would be easier to use '@' to match the file, and, to be on the safe side, add a -i flag to rm: rm -i *@*. The command rm will ask if you want to remove the files that match one by one, so you can choose to say yes or no. For the "Original Question", he may use rm -i *E@X* (safer to use three characters). –  Oct 03 '18 at 01:28
  • rm -i: sure, safer. In this case "I know what I am doing"TM. Then, as suggested, rm -i *E@X* did not work. – Gen.Stack Oct 03 '18 at 14:34
  • I wonder what all those downvotes are about.. surely nothing about the facts.. – Gen.Stack Oct 04 '18 at 13:31
  • well, [https://unix.stackexchange.com/questions/28983/how-can-i-delete-a-file-which-filename-has-non-printing-characters] lists a couple of ways to get rid of such a file. It seems to me by far the easiest way to remove it using rm ./???E@*, compared to throwing find at it or typing rm $'\177', let alone other solutions presented. Pick your favourite. I for sure see no reason to downvote. It is an additional viable and correct solution. – Gen.Stack Oct 04 '18 at 13:39
-1

I dont know what the fuss is about. Escape characters do just fine for me. I would just tab out the file name and it adds escape characters to itself.

rm -f \?\?\?E@X\?p@8\?@

Earlier when I had a file starting with --, I would just add the path before the file name and quote the file name like below.

rm -f ./'--exlude=ssh'