在Shell脚本中使用带空格的路径
问题描述:
我正在使用shell脚本来调用java程序。当调用传递Java程序时,我正在传递具有目录路径的-Dargument。这个-D参数是从文件中读取的。现在,当这条路径包含空格时,我正面临一个问题。我试着用报价和转义报价,但都努力工作。在Shell脚本中使用带空格的路径
这里是我的shell脚本代码,test.sh
D_ARG=`(tr '\r\n' ' ' < argument.dat)
\#executing java code by passing above argument
java ${D_ARG} TestProgram
下面是我的参数文件,argument.dat
-Dargument1="/Path /To A/File"
当我设置回音使用设置-x,我见外壳将其转换为
'-Dargument1="/Path' '/To' 'A/File"'
如果它增加了,当它遇到的空间,我得到单引号“/”未找到类除外离子。如何解决这个问题。任何建议或帮助将非常可观。
答
试试这个:
ARGS=
# Do nothing if there are no spaces; if there are spaces, surround with quotes
for arg in $(perl -pe '//or next; s/^/"/; s/$/"/' argument.dat); do
ARGS="$ARGS $arg";
done
java $ARGS TestProgram
这基本上有每次行有一个空间,它的作用,它会与引号包围,所以-Da=b c
会变成"-Da=b c"
。
注意"-Da=b c"
严格等同于-Da="b c"
,甚至更离奇的前瞻性它的形式:
-
'-Da='b\ c
; -
-D"a=b "c
; - 等等等等
其中重要的唯一的事情是,无论字符输入字段分隔符转义。是的,这是合法的:
alias l"l=ls"\ -l
答
您可能会转义“/ Path/To A/File”中的空格。然而,这不是一个很好的解决方案,因为很多时候,我们可以制定这样的命令在Linux系统上
system(argv[1]);/* Example is C specific;
but you understand the loop-hole imparted by single escaping.
You may require multilevel escaping, based on your implementation. OR
We may have to escape the string, every time it is dereferenced.
*/
更好的选择是创建符号链接。
ln -s "/Path /To A/File" /tmp/file
&那么在参数文件中,使用-Dargument1="/tmp/file"
使用此方法,如果只有一个有问题的文件"/Path /To A/File"
。
另一种方法是使用mount --bind
mkdir /tmp/myfiles && mount --bind "/Path /To A" /tmp/myfiles
&那么在参数文件中,使用-Dargument1="/tmp/myfiles/File"
这种做法将安装"/Path /To A"
到/tmp/myfiles
。其中的所有文件&目录结构将被保留。
答
该脚本在与eval命令一起使用时保持工作状态,该命令保留了引号,并且它添加了任何其他单引号。
D_ARG=`(tr '\r\n' ' ' < argument.dat)
\#executing java code by passing above argument
eval java ${D_ARG} TestProgram
但如果我必须在argument.dat文件中定义多个参数,那么双方的观点被认为是一个字符串,因为你有没有指定的参数报价“$ {} D_ARG” – Mojoy
在原始问题中告诉它);在这种情况下,你的'tr'命令不是处理这个问题的方法。 – fge
查看编辑后的解决方案 – fge