17

As you can see below the files have uncommon characters.

file manager screenshot

Deleting them either in the terminal or Dolphin returns the error:

No such file or directory

Running ls -la on the directory gave me this output:

-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ?2?.???љ?!?Gb??σ?[?F?
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 3l??#g?w????O?JKB7?co??քH??bT?NA???S???X?I?A?qC??M?I???
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??8??-?@,?Zp?[?bI????7^?ñ[?ڏ??z?O???ч??eEȰ?+??,OF??h

I ran an fsck command on the partition from another OS but it didn't change anything.

How do I remove these files?

  • 1
    Did you set up your system to have an encrypted home directory? – dobey Dec 30 '17 at 17:48
  • @dobey I did not. – karjedavpalaa Dec 30 '17 at 17:50
  • 5
    @Panther You are mistaken. This is not, by itself, an indication of a corrupt file system, and even if it was caused by data corruption of some kind, fsck won't do anything about it. – zwol Dec 30 '17 at 22:58
  • 1
  • 1
    I've had files with unrecognized charaters in the name. Renaming the files worked. then they could be deleted. – ravery Dec 31 '17 at 15:50
35

A simple way would be to remove these files by their inode. :)

Use ls -li in the directory with the uncommon characters to show the inode number of each file, e.g.,

$ ls -li
total 0
133370 -rw-r--r-- 1 malte malte 0 Dec 30 19:00 ?2?.???љ?!?Gb??σ?[?F?
132584 -rw-r--r-- 1 malte malte 0 Dec 30 18:59 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??

Next, use the find utility to delete the corresponding file by its name, using the syntax find <somepath> -inum <inode_number> -exec rm -i {} \;, as in the following example:

$ find . -inum 133370 -exec rm -i {} \;
rm: remove regular empty file ‘./?2?.???љ?!?Gb??σ?[?F?’? y
$ ls -li
total 0
132584 -rw-r--r-- 1 malte malte 0 Dec 30 18:59 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??

The -i option to rm is not really necessary, I just added it to keep you from accidentally removing files you didn't mean to remove. :) It causes rm to ask for confirmation for each file that you want to delete.

If you want to remove multiple files by their inodes, you can use the -o (meaning or) syntax for find:

$ find .  \( -inum 133370 -o -inum 132584 \) -exec rm -i {} \;
rm: remove regular empty file ‘./?2?.???љ?!?Gb??σ?[?F?’? y
rm: remove regular empty file ‘./??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??’? y

You can add more inode numbers by extending the expression in parentheses with more -o -inum <inode_number> expressions.

  • 4
    How about rm -ri .? – Brent Baccala Dec 30 '17 at 18:37
  • This worked: find <somepath> -inum <inode_number> -exec rm -i {} \; What does '-inum', '{}', and '\' do in the command? – karjedavpalaa Dec 30 '17 at 19:49
  • How do I remove multiple files at one go? Also, thank you, you made my day! – karjedavpalaa Dec 30 '17 at 19:51
  • 2
    @BrentBaccala rm -ri . is not deleting files by inode, though. It will simply recurse through the entire working directory and ask for each file if you want to remove it - and you have to be very attentive which files it is asking for so as not to accidentally remove unwanted ones. I certainly would not want to use this command for my home directory - it contains LOTS of files. ;) – Malte Skoruppa Dec 30 '17 at 20:43
  • 3
    @karjedavpalaa (1) -inum tells find to look for files by their inode number. (2) {} matches the file(s) found by grep. (3) \ escapes the ; symbol which terminates the command passed to the -exec option of find. (4) I have edited my answer to explain how to remove multiple files in one go. – Malte Skoruppa Dec 30 '17 at 20:54
13

It is important to understand that this is not the kind of "filesystem corruption" that fsck will help with. As far as the filesystem is concerned, file names can be any sequence of bytes, as long as no single byte has the value 0x00 (ASCII NUL, C end-of-string marker) or 0x2F (/, the directory separator). (If a file name does somehow get a 00 or 2F byte embedded within it, fsck should fix that.)

Rather, what you have is file names that application software (Dolphin, ls) think contain characters that are un-displayable in your "locale", so it is replacing them with placeholder characters. You can't type those characters either, so manipulating the files is harder, but you can do it as long as you do it without ever typing or copying and pasting the name. For instance, if you delete or rename the problem files directly from within Dolphin, that should Just Work (I would go so far as to say that if it doesn't work, that's a bug in Dolphin).

If you need to do something about them from the shell (for instance, if they are owned by root and therefore cannot be modified by a GUI program), you can name them indirectly using "glob" patterns, which will be expanded to the correct sequence(s) of bytes and passed along.

Now, of course, you wouldn't want to delete stuff by accident because your glob pattern matched too much, so my recommendation would be to use the Perl rename utility to convert each filename to its hex encoding:

$ rename '$_ = unpack("H*", $_)' *

This doesn't destroy any information - neither the file itself, nor whatever meaning might originally have been encoded in the filename before it got mangled. It can be undone for specific files with e.g.

$ rename '$_ = pack("H*", $_)' 696d706f7274616e742e646f63

Caution: there are two programs named rename, from different origins; the above commands will only work with the one originating with Perl. In Ubuntu, the one you want is the one from the "rename" package, not the one from the "util-linux" package. rename -h will distinguish: this is what you want...

$ rename -h
Usage:
    rename [ -h|-m|-V ] [ -v ] [ -n ] [ -f ] [ -e|-E perlexpr]*|perlexpr
    [ files ]
# ...

... this is not what you want ...

$ rename -h

Usage:
 rename [options] <expression> <replacement> <file>...
# ...

The key thing to look for is "perlexpr". You might have an older version of the Perl rename that doesn't understand all of the options above, but the command I showed should still work.

Edit: Under 14.04 .5 the perl script that's included for rename does not support the -h switch. You can confirm you have the correct one by checking it's man page with man rename in which case the top line will contain:

RENAME(1) Perl Programmers Reference Guide RENAME(1)

  • rename --version Unknown option: version – Elder Geek Jan 10 '18 at 16:03
  • @ElderGeek What does file $(which rename) print? (Make sure you have the file package installed, first.) – zwol Jan 10 '18 at 16:36
  • /usr/bin/rename: symbolic link to /etc/alternatives/rename (file is installed by default) Actually you have to chase down the symbolic links to get /usr/bin/file-rename: a /usr/bin/perl -w script, ASCII text executable but man rename is a quicker indication... – Elder Geek Jan 11 '18 at 14:50
  • @ElderGeek If it's a perl script, then it's probably an older version of the "one originating with Perl", that doesn't support --version; the command I suggested should still work. (/usr/share/doc/rename/changelog.gz on my computer, which runs Debian unstable, indicates that --version was added in version 0.10 of the Perl rename, in 2013. I'm surprised Ubuntu is still shipping something older than that, but this program hasn't actually changed its functionality since 2007(!) so it's fine.) – zwol Jan 11 '18 at 14:57
  • Ah! That explains the confusion. Despite many claims to the contrary, Debian is not Ubuntu. I can't speak for every release, but some currently supported versions of Ubuntu LTS (14.04) still doesn't have that. (Although 16.04 does) – Elder Geek Jan 11 '18 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.