How can I deal with pathnames that include problematic (= shell meta and space) characters?
Often I have files with weird names like /foo/bar * baka/waka xoxotinh(|).mp3
. What is the correct way to escape this thing in an arbitrary language in order to co开发者_运维百科rrectly reference the file?
Escape each reserved character with a \
:
/foo/bar\ \*\ baka/waka\ \*\ xoxotinh\(\|\).mp3
or put it in quotes like this:
"/foo/bar * baka/waka * xoxotinh(|).mp3"
You can escape it by including the whole path in ''
or by escaping individual "weird" chars by \
.
This is not always an easy task, so if you do it right from bash prompt, then just use TAB
to complete the path - bash will escape "weird" chars for you.
Here's how bash escaped it:
cd /foo/bar\ \*\ baka/waka\ xoxotinh\(\|\).mp3/
Note: I've created the path by:
mkdir -p '/foo/bar * baka/waka xoxotinh(|).mp3'
In an arbitrary language, it depends entirely on the language, and its quoting conventions. In most languages I am familiar with, your example file name is not particularly problematic, except in shell script; in sh and derivatives, use single quotes for this sort of thing.
You need to either add the filename between quotes like "asd * sdd||ss.mp3"
, or escape characters. Escaping means you need to add a \
before each invalid character.
in php you have http://www.php.net/manual/en/function.escapeshellarg.php for example
In BASH, you can use double quotes to remove the globbing meaning of *
and ?
. Backticks are a bit more troublesome. You'll have to double up those.
In fact, you can simply add a backtickslash in front of any non-alpha numeric character in Bash and be quite safe. This worked quite nicely in Bash on Linux:
newFileName=$(echo -E "$fileName" | sed 's/[^[:alnum:]]/\\/g')
There is no general solution other than to quote each shell meta character and whitespace with a backslash. If you quote with 'single quotes' there's the problem with names containing a single quote. If you quote with "double quotes" there's the problem with names containing double quotes and dollar signs. And of course there are names containing both... But you can quote parts of names with different quoting styles:
ls "name with spaces & a single quote->'"' and name with "quotes" and $'
Note how the second double quote ends the first part, and the next character is the single quote that quotes the remainder. There! Quoted a name containing both quotes! Once the shell has performed quote removal (always last), ls
will see
name with spaces & a single quote->' and name with "quotes" and $
as a single argument.
精彩评论