Bash的内置命令printf
支持%q格式字符串,它转义shell输入变量的内容。
我尝试了一些选项::q
只转义了空格,而gnu printf不支持%q
。
目前,我使用以下代码:
set valq = `echo $val:q | bash -c 'read q;printf %q "$q"'`
/path/to/executable $valq
我不喜欢有bash依赖性的csh脚本。这有什么csh原生解决方案吗?
感谢。
这是一个测试代码,用于说明我遇到的问题。
wrapper.csh
#!/bin/csh -f
set i = 1
set tst1 = ""
set tst2 = ""
while ( $i <= $#argv )
set arg = "$argv[$i]"
set tst1 = ($tst1:q $arg:q)
set arg2 = `echo $arg:q | bash -c 'read q;printf %q "$q"'`
set tst2 = "$tst2:q $arg2:q"
@ i = $i + 1
end
echo "====case 1===="
./test.csh $tst1:q
./test.csh $tst1
./test.csh $tst2
echo "====case 2===="
csh -cf "./test.csh $tst1"
csh -cf "./test.csh $tst1:q"
csh -cf "./test.csh $tst2"
test.csh
#!/bin/csh -f
echo -n "TEST ARG:"
set i = 1
while ($i <= $#argv)
echo -n "${i}:$argv[$i] "
@ i = $i + 1
end
echo
测试结果1:
>./wrapper.csh "a ()" b c
====case 1====
TEST ARG:1:a () 2:b 3:c
TEST ARG:1:a 2:() 3:b 4:c
TEST ARG:1:a\ 2:\(\) 3:b 4:c
====case 2====
Badly placed ()'s.
Badly placed ()'s.
TEST ARG:1:a () 2:b 3:c
测试结果2:
bash>./wrapper.csh "'\"a ()" b c
csh>./wrapper.csh "'"'"'"a ( ) " b c
====case 1====
TEST ARG:1:'"a () 2:b 3:c
TEST ARG:1:'"a 2:() 3:b 4:c
TEST ARG:1:\'\"a\ 2:\(\) 3:b 4:c
====case 2====
Unmatched '.
Unmatched '.
TEST ARG:1:'"a () 2:b 3:c
测试摘要:
如果在csh中直接调用命令,则$val:q
是正确的用法。
如果命令是通过参数传递的,则printf %q
是正确的用法。
答案 0 :(得分:0)
只需使用/path/to/executable "$val"
。
如果变量在"
内扩展(如在csh -cf "test.csh $tst1"
中),并且要保留特殊字符和多个单词,则必须确实引用这些单词。但printf
的特殊bash
对此并不是必不可少的;我们可以做到这一点。 G。用:
set tst1q=`printf " '%s'" $tst1:q`
csh -cf "test.csh $tst1q"
(正常printf
没有%q
)。
要同时允许"
和'
,您可以在最初执行
set s='s/[] "$&-*;<>?`|~[]/\\&/g'
将bash -c 'read q;printf %q "$q"'
替换为sed "$s"
中的wrapper.csh
。
正则表达式
[] "$&-*;<>?`|~[]
是括号表达式,[]
中包含的字符列表。它匹配单个字符,该字符由替换\\&
加上反斜杠(特殊字符&
表示匹配的字符)。我没有包含字符,
和^
(它们由printf %q
转义,但在csh
中不需要),而我包括~
(它不会被printf %q
转义,但必须位于csh
- 尝试wrapper.csh "~"
)。