为 bash 转义文件名

来源:互联网 发布:海贼王霸气败笔知乎 编辑:程序博客网 时间:2024/05/16 12:15

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 的实现

[ruby] view plaincopy
  1. function shquote(s)  
  2.     return "."..string.gsub("'""'\''").."'"  
  3. end  

0 0
原创粉丝点击