另一个 Bash 脚本生成的引号不被视为原始脚本中的引号

另一个 Bash 脚本生成的引号不被视为原始脚本中的引号

使用 bash,我的pwd目录包含带空格的目录:

$ pwd
/a/b c/d

这有效:

$ ls "$PWD"
bar foo
# yay!

如果我将该代码放入脚本中,它也会起作用。现在,如果我将该命令分成两部分:

$ cat foo 
echo \"$PWD\"
$ cat bar 
ls $(./foo)

foo生成引用的路径:

$ ./foo 
"a/b c/d"
# ok

bar没有按照我期望的方式处理引号:

$ ./bar 
ls: "/a/b: No such file or directory
ls: c/d": No such file or directory
# boo!

这不是学术性的。我实际上想要拆分的命令是可怕的。我不想将其放在单个脚本中,而是想将其分成两个脚本:一个生成正确引用的参数,另一个大大简化(并调用第一个脚本)。碰巧这个可怕的参数列表对于多个命令很有用,因此这是将其放在单独的脚本中的另一个原因。

更新1:顺便说一句,这有效:

$ cat foo
ARGS="$PWD"
$ cat bar
source ./foo
ls "$ARGS"
$ ./bar
bar foo

但将参数放入变量中似乎很做作。

更新2:@user454038 的解决方案适用于目录名称中的单个空格,但在两个空格处中断。

更新3:@mikeserv 和 @user454038 对我进行了充分的教育,使我能够正常工作(对于目录名称中的一个和两个,可能还有更多空格):

$ cat foo 
echo "$PWD"
$ cat bar
ls "$(./foo)"

我们开始吧!谢谢大家!

答案1

正如@mikeserv 指出的那样,问题在于引号。多余的报价。解决方案是foo首先不要在您的引号中包含引号:

dir 结构(我们有 cd 到该d目录):

~
└── a
    └── b c
        └── d

ddir 中,我们已经foobar您发布了。但现在创建:

foo2:

echo $PWD

bar2:

set -x
ls "$(./foo2)"
  • 我们有set -x这样你就可以清楚地看到发生了什么

当您/bar在命令提示符下运行时,您会看到:

$ ./bar2
+++ ./foo2
++ ls '/home/youruser/a/b c/d'
bar  bar2  foo  foo2

set -x只需从代码中删除,即可成功获得所需的输出:

bar  bar2  foo  foo2

解释

如果你添加set -x到原来的bar,然后运行,你会看到

$ ./bar
+++ ./foo
++ ls '"/home/youruser/a/b c/d"'
ls: cannot access "/home/youruser/a/b c/d": No such file or directory

这与在命令提示符下运行的效果相同:

$ ls '"/home/youruser/a/b c/d"'
ls: cannot access "/home/youruser/a/b c/d": No such file or directory
  • 罪魁祸首是额外的"报价
  • 这是在你的原文中介绍的foo
  • 一旦"移除,就ls可以工作

因此,删除原始 中的引号foo(正如我们对 所做的那样foo2)可确保ls正确接收它而不会出现过多的引号,然后它就可以工作。

相关内容