简体   繁体   中英

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 correctly 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 back tick slash 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM