Dealing with Funny Files
Dealing with Funny Files
Sometimes AIX reports an odd file when you use an ls or find command but it’s not present on the system. It can be frustrating when you can’t remove it due to special characters in the file name. When presented with these type of file or filename, I call them funny files. To solve these types of issues, you need to use i-nodes and escape characters to remove them, and if all else fails then fsck is your friend.
My File Contains Funny Characters
Don’t you just hate it when users transfer text files onto AIX, then complain their script or program isn’t running as expected due to format errors in their files. Generally, it’s because they haven’t transferred them using the correct transfer mode (i.e., using FTP), thus they are full of control characters. If you think this is a possibility, you can test using ‘ cat –v’: looking at a small file with the control character 15 (^M), which is a carriage return embedded in the file:
# cat -v myfile.txt CONFIG=1223^M
However using cat with no options, shows no clues as to what is wrong with the file:
# cat myfile.txt CONFIG=1223
Another way to display special characters in a file is to use ‘od –c, which displays them in octal values’:
# cat myfile.txt | od -c 0000000 C O N F I G = 1 2 2 3 \r \n 0000015
In this example, it’s a small file, so we can just go ahead and remove the . However large files will require a utility that will clear these characters in one sweep. There are a few out there that will do it, but let’s look at sed and tr. First, sed:
# sed s/^M//g myfile.txt >tmp.file # mv tmp.file myfile.txt
In this example we use sed, where the ‘^M’ contained in the sed command line is actually a : plus key. The ^M’s are replaced with nothing, denoted by ‘//’, thus removing character. Then we redirect to a temp file then move it back to the original file. Next, tr:
# tr -d '\015' tmp.file # mv tmp.file myfile.txt
Here we remove all carriage returns (control character 15, as seen from the odd output earlier) denoted by the ‘-d \015\’ from the file and redirect the output to a temp file, before moving back to the original.
Removing Those Funny Filenames
It happens to all of us: We’re doing a pattern search through filenames and decide to redirect the output to another file. We then realize we have put a special character into the output filename by mistake. Oops! Or you realize you have a large problem as several users have transferred files from Windows with spaces or other special characters in the filename. These must be removed or renamed to the standard character range, or some processes won’t be able to open the file.
Typical examples of filenames with funny names or more strictly speaking containing special characters are:
>myfile my>file my\file my #file -myfil e
There are other weird filenames for sure, but this list more or less encompasses what you can expect. To remove these types of filenames, you’ll either need to use quotes or a backslash when removing them with the rm command. But here’s a tip: Always try it with the ls or cat command first before committing with the rm command, so you don’t get unexpected results in the pattern criteria you’re using to remove the file. You don’t want to remove more files than you bargained for!
Looking at the first example, ‘>myfile’, if you do an ls on this filename the output will overwrite the actual file, due to the redirection ‘>’ character at the beginning. To avoid this, use the cat command to confirm. Putting a backslash at the beginning will allow you to cat the file:
# cat \>myfile My file
So we only need to backslash it when removing it, like so:
# rm \>myfile
Using the backslash removes any meaning off the next character.
Looking at the next example, ‘my>file’, though it looks nasty, the same backslash technique can be used to remove it:
# cat my\>file # rm my\>file
With ‘my\file’, we actually have a backslash in the filename, so we can simply backslash the backslash:
# rm my\\file
For ‘my #file’, again backslash is your friend:
# rm my\ \#file
If you make sure you have a space after the first backslash, the file will be found and removed.
Finally, with ‘-myfil e’, we need to use a period at the beginning followed by a forward slash. This tells the shell not to interpret the special characters as part of the command, which it will do by default. We simply enclose the whole command in single quotes to prevent the space being misinterpreted by the shell, and it will be removed. As before, always use the cat or ls command first, before committing with the rm command:
# cat './-myfil e' # rm './-myfil e'
Cannot Remove This File No Matter What
There will be occasions when you’ve tried everything to remove a funny filename, but it just won’t go. You need to look at another way of attacking the problem. Using i-nodes may be your solution.
Suppose we have a filename, £myfile, that just won’t be removed using quotes or backslashes with the rm command. Find the i-node of the filename and remove it that way. To do this, run the ls command with i-node option to find the i-node of the file:
# ls -altsi|head total 76 6 4 drwxr-xr-x 3 dxtans staff 4096 Jul 19 14:34 . 77 4 -rw-r--r-- 1 root system 993 Jul 19 14:34 £myfile
We learn the i-node for the file £myfile is 77. Now we can remove it using find and xargs. First though we make sure we can locate it with the find command before actually removing it:
# find . -inum 77 ./£myfile # find . -inum 77|xargs rm
The file is now removed.
Your find command is INCREDIBLY dangerous. You just removed inode 77 in your filesystem and every filesystem mounted below it. So if your file was in / you just deleted inode 77 from every filesystem on the box. Add -xdev to the find command to prevent that!
find . -inum 77 -xdev -exec rm {} \;
fsck Is Your Friend
You may run a mksysb on a system and it reports that it cannot find a filename, with errors such as:
find: 0652-019 The status on is not valid.
It’s most probable that, at some point, one of the following events happened:
- The file was present when mksysb started but was removed immediately after while mksysb was gathering the list of files to back up
- This was a NFS mount that was pulled (unmounted forcibly)
If you’re sure the file was present but cannot be found by i-node, then unmount the file system in question and run a fsck to fix the i-node count. It maybe be prudent to have the “check=true” for your application based filesystems in /etc/filesystems to allow fsck to be performed upon a reboot.
However, if this file is root (/) ,/var or /tmp, you can try a reboot as fsck is ran as part of the bootup process. This may fix the issue for you. If it doesn’t, then you will need to boot into maintenance mode first, then run fsck. As you are probably aware, running a fsck on a mounted filesystem can produce unexpected results!
I hope these tips helped you solve your funny file problems.