在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 
+0

但如果我必须在argument.dat文件中定义多个参数,那么双方的观点被认为是一个字符串,因为你有没有指定的参数报价“$ {} D_ARG” – Mojoy

+0

在原始问题中告诉它);在这种情况下,你的'tr'命令不是处理这个问题的方法。 – fge

+0

查看编辑后的解决方案 – fge

您可能会转义“/ 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