http://blog.csdn.net/shell_picker/article/details/7415030
最近遇到的一個問題:在程序中有一個文件名,需要生成並執行一個 shell 命令,比如通過 os.execute 執行。但這個文件名可能包含特殊字符。
比如,如果文件名是:這個文件名不能直接在 shell 命令中使用
[SumiSora&CASO&HKG][Tears_to_Tiara][02][GB].rmvb
那麼轉義之後就是:
\[SumiSora\&CASO\&HKG\]\[Tears_to_Tiara\]\[02\]\[GB\].rmvb
或者採用單引號的辦法:
'[SumiSora&CASO&HKG][Tears_to_Tiara][02][GB].rmvb'
經過一些搜索:
http://stackoverflow.com/questions/35817/how-to-escape-os-system-calls-in-python
http://stackoverflow.com/questions/5608112/escape-filenames-using-the-same-way-bash-do-it
我找到了 bash 的內置命令 printf "%q" str 可以實現這個功能,於是下載了 bash 的源代碼來看。首先定位到 builtins/printf.def 文件,其中 q 的部分調用了以下函數:
ansic_shouldquote
ansic_quote
sh_backslash_quote
前兩個函數在 lib/sh/strtrans.c 中,後一個函數在 lib/sh/shquote.c 中。所以最後終於定位到 shquote.c 這個文件。
1. 如果要使用單引號轉義,那麼使用 sh_single_quote 的算法
2. 想用反斜線轉義,使用 sh_blackslash_quote 的算法
## 實現
出於方便考慮,我只實現了單引號轉義,下面是一個 lua 的實現
- function shquote(s)
- return "."..string.gsub("'", "'\''").."'"
- end