Taken from:
http://linux.dsplabs.com.au/chmod-invalid-mode-dealing-with-a-leading-minus-in-filenames-under-linux-shell-p37/Dealing with files whose filenames contain special shell characters can be tricky. Unless you know how to handle their filenames properly, you may not be able to perform even simple operations on such files. In this post I’ll show you how to deal with files starting with the minus (-) character, as well as with files that contain spaces. Let us consider a simple example. I’ll start with a pdf file <code>outline.pdf</code> and rename it so that the resulting filenames start with special shell characters.
OK, running
ls -la
produces the following output
total 2308
drwx------ 2 kamil kamil 4096 Nov 26 19:17 .
drwx------ 3 kamil kamil 4096 Nov 26 19:13 ..
-rw------- 1 kamil kamil 465135 Nov 26 19:14 ~ outline.pdf
-rw------- 1 kamil kamil 465135 Nov 26 19:16 ~outline.pdf
-rw------- 1 kamil kamil 465135 Nov 26 19:15 -outline.pdf
-rw------- 1 kamil kamil 465135 Nov 26 19:15 .outline.pdf
-rw------- 1 kamil kamil 465135 Nov 26 19:13 outline.pdf
As you can see number of special shell characters are used, such as the tilde character (<code>~</code>), which in shell points to the home directory of the current user, the minus character (<code>-</code>), which is used for escaping command options for shell programs as well as in IO redirection, and the dot character (<code>.</code>) that stands for the current directory. Now lets try to apply a file operation to all of these files in a typical way. More specifically, lets make these files readable by everyone using the following command
chmod a+r *.pdf
The above command fails with the following error message.
chmod: invalid mode: `-outline.pdf'
Try `chmod --help' for more information.
So, the <code>chmod</code> operation fails because the minus in the <code>-outline.pdf</code> filename is considered a mode switch, with a non-existent mode: <code>outline.pdf</code>. Out of the above files, <code>-outline.pdf</code>, is the only file that causes problems since running the following command works fine.
chmod a+r ~outline.pdf .outline.pdf outline.pdf ~\ outline.pdf
This is shown in the output below.
total 2308
drwx------ 2 kamil kamil 4096 Nov 26 19:17 .
drwx------ 3 kamil kamil 4096 Nov 26 19:13 ..
-rw-r--r-- 1 kamil kamil 465135 Nov 26 19:14 ~ outline.pdf
-rw-r--r-- 1 kamil kamil 465135 Nov 26 19:16 ~outline.pdf
-rw------- 1 kamil kamil 465135 Nov 26 19:15 -outline.pdf
-rw-r--r-- 1 kamil kamil 465135 Nov 26 19:15 .outline.pdf
-rw-r--r-- 1 kamil kamil 465135 Nov 26 19:13 outline.pdf
Note, that in the above command the space in the <code>~ outline.pdf</code> filename was escaped using the backslash (\) character, otherwise the <code>chmod a+r</code> operation would be applied to the home directory (~) and the <code>outline.pdf</code> file, instead of the <code>~ outline.pdf</code> file.
So how to get around the leading minus in filenames under Linux shell? Well it is simple, you just have to make sure that there are no leading minuses in the file names. How is that accomplished? By specifying filenames with leading
paths. In our example with the current directory, hence the following command would make all the files readable for all the users.
chmod a+r ./*.pdf
In the above command, by pre-pending a <code>./</code> to the <code>*.pdf</code> wild card string we eliminate the problem previously caused by the minus. This is because the minus is no longer the leading character in any of the filenames. Instead, all of the files passed to the <code>chmod a+r</code> command begin with <code>./</code> string. To change permissions on the <code>- outline.pdf</code> file alone the following command can be used.
chmod a+r ./-outline.pdf