8

While unpacking a tarball, I encountered a directory which ls reports as "??????????????? ?????". Presumably, the name is not in unicode? Anyway, I can't figure a way to access the folder. I've tried cd $(find -inum inode_number), but that gives me

"bash: cd: ./??????????: No such file or directory".

Is there another way to access a folder directly by its inode number?

3
  • Is it perhaps lexically first in the directory listing? Then cd */ might work. * should expand a shell understandable description of the directory, and cd ignores extra arguments. Another way might be to use a graphical file manager (including the terminal based MC) or the built-in file tree navigators in e.g. Vim. You can also experiment with the -exec switch to find, not with cd` directly (which is a shell built-in) but with e.g. ls and other tools. Jan 12, 2013 at 8:33
  • @Daniel: In some shells, cd with multiple arguments fails. Jan 14, 2013 at 0:51
  • @Scott: True. POSIX does not specify behavior of multiple arguments. Bash and Dash ignore extra arguments, csh exits with "too many arguments". Jan 14, 2013 at 6:38

7 Answers 7

3

A general approach to be able to operate on any directory (or file) is to use its inode number.

First, use ls to get the inode of the folder in question:

ls -lia
  • -l for long listing (optional)
  • -i to get inode values
  • -a to view all files, even hidden files (optional)

In the listing you'll see a long number in the first column, something like this:

2104697 drwx------ 2 user group 4096 date time WEIRD_DIRNAME

Now you can change to that directory using:

cd "$(find -inum ######)"

...but substituting ###### with the long number that you got in the directory listing.

Of course the command doesn't have to be cd. It could be rm, cp, mv, etc...

2

Since the characters are likely international characters, they likely are appearing as control codes in your en_US character set, which is why ls is showing them as question marks.

This may be due to your distribution's choice of alias'ing ls by default in the global profile. For example:

alias ls='ls -q'

You can see if your distribution has done so by typing into your shell:

alias ls

Which will print out something like the following:

$ alias ls
alias ls='ls --color=auto'

The page linked below suggests that if you do "ls -b", you will see the octal control codes so you know at least what characters are in use.

http://www.arsc.edu/arsc/support/howtos/nonprintingchars/

Assuming that doesn't work you have another option also mentioned there nearer to the bottom:

A tool I was unaware of until now called OctalDump (on Debian -- /usr/bin/od)

$ ls | od -b

Will show you the octal form of the control codes.

$ ls | od -c

Will show you the characters including any hidden additional whitespace that might be at the end (note the extra spaces on the end in their example)

Once you know what control characters are in play and whether there is additional hidden whitespace, you may be able to finagle a way to cd to the directory by escaping the control characters. Failing that, you have a couple of options for renaming the directory.

The page above also, conveniently, has a quick and dirty method for removing the control characters via the mv command, which I think will work, so long as you DO escape the space, but DONT escape the question marks (thusly making them single character wildcards), and so long as nothing else exists in the directory where this rogue directory is. The reason for these explicit requirements is because you're using only wildcard characters and the single space, and so you don't want the wildcard to inadvertently match any other file or directory.

If the above method does not work, you can almost assuredly use the find method mentioned by other responses, in a different way. Rather than trying to cd to the directory using the inode number, which is what you said you have tried, you can rename it using the inode number. Just be sure to copy the entire set of 3 lines for that one command from the page above (replace the "desired-name" part with the actual name you want to rename it to however).

Once the directory is renamed, then you should be able to access it. I can only hope that it doesn't also contain files with control codes in the names, or you will have to rinse and repeat for every file (and/or subdirectory) in the directory you just renamed, at which point a for loop would probably be wise to just name every file as a number, by incrementing from 1. :-)

0

"?" has a special meaning in the shell, it means "any character, including none". So if your file is really named "??????????????? ?????" you probably have to escape the "?" (and spaces toos) so you could try something like cd \?\?\?\?\?\?\ \?\?\?\? (if you didn't try already)

That's assuming someone intentionnally gave the file that tricky name, rather that garbled/corrupted/illegal encoding.

1
  • 1
    But remember that ls likes to display non-ASCII characters (≥0x7F) as ? –– so the directory name probably isn’t just a string of question marks. Jan 14, 2013 at 0:46
0

Do an ls.  Is there anything in the directory (file or subdirectory) with a name that’s longer than your mystery subdirectory (which is 21, if your “??????????????? ?????” is accurate)?  Then rename them to shorter names or move them into other directories.  Then type

cd ????????????????????*

This wildcard (20 question marks followed by an asterisk) should match any name that is 20 characters long or longer –– and the first instruction I gave should have ensured that your mystery subdirectory is the only thing that matches that pattern.  But it might be more useful to do

mv ????????????????????* new_name

2
  • 3
    It might be helpful to run ls with the either --quoting-style=shell or --quoting-style=escape option to force it to produce a properly escaped version of that file name.
    – Dan D.
    Jan 14, 2013 at 2:14
  • 1
    @DanD. +1 for cool option I didn't know about. I usually just use a gui file manager when something like this has to be dealt with, but it might come in handy if I have to work from a console or within a script.
    – Joe
    Jan 15, 2013 at 5:53
0

One easy way to see what's in there is to FTP to the machine with FileZilla. Then you can use FileZilla to rename the directory.

0

Use a file browser such as Midnight Commander (text), Nautilus (GNOME) or Dolphin (KDE) to work with the directory.

0

to work with directories (or files) that have weird/hard to type names:

1) Run ls -i to discover the inode of the file.

This ls option will give you each name of file, and a identifier for this file on the file system (the inode)

2) Use find to run a command on the file

say the inode was 9961926

you could run

 find * -prune -inum 9961926 -exec rm -i {} \;

to delete the file

or

 find * -prune -inum 9961926 -exec mv {} other-name \;

to move it to a better name

or even

 find * -prune -inum 9961926 -exec ln -s {} non-horrible-name \;

to give it a new name while keeping the old name

(presumably, you could run other commands as well. Unfortunately I could not use this line to run a cd)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .