【问题标题】:Have bash interpret double quotes stored in variable containing file path让 bash 解释存储在包含文件路径的变量中的双引号
【发布时间】:2021-10-04 16:41:56
【问题描述】:

我想捕获一个在 bash 变量中包含空格的目录,并将其传递给ls 命令没有 用双引号将变量引用括起来。以下是说明问题的两个示例。示例 1 有效,但它涉及键入双引号。示例 2 不起作用,但我希望它起作用,因为这样我可以避免输入双引号。

示例1,用引号括住变量,如How to add path with space in Bash variable的解决方案,但不能解决问题:

[user@machine]$ myfolder=/home/username/myfolder\ with\ spaces/
[user@machine]$ ls "$myfolder"
file1.txt file2.txt file3.txt

示例 2,带引号的变量部分,同样不能解决问题。根据我的理解,在这个例子中,在抛出错误之前发送给ls命令的第一个引号字符:

[user@machine]$ myfolder=\"/home/username/myfolder\ with\ spaces/\"
[user@machine]$ ls $myfolder
ls: cannot access '"/home/username/myfolder': No such file or directory

在示例 2 中,错误消息表明第一个双引号被发送到 ls 命令,但我希望这些引号被 bash 解释,而不是 ls。有没有办法可以更改 myfolder 变量,以便第二行的行为完全如下:

[user@machine]$ ls "/home/username/myfolder with spaces/"

我们的目标是制作 myfolder 变量,使 (1) 它不需要被任何字符包围,并且 (2) ls 命令将列出它所在的现有目录的内容代表。

动机是有一个有效的速记,以尽可能少的字符将包含空格的长目录路径传递给命令行上的可执行文件 - 如果可能的话,不要使用双引号。

【问题讨论】:

  • 你可以使用eval ls $myfolder,但是这会增加5个字符来保存2个引号。
  • 感谢您的提示!我想我可以为“eval ls”创建一个别名,例如: alias lse="eval ls" 然后将其用作: lse $myfolder
  • 请注意,eval 还将处理任何其他 shell 元字符,而不仅仅是引号。如果有;字符,则将其拆分为多个命令,并执行。
  • 例如myfolder="foo;rm *" 将删除所有内容。
  • 双引号变量是唯一可靠的解决方案。除非你想切换到 zsh...

标签: bash escaping quotes substitution


【解决方案1】:

假设ls 命令之前的一些“额外”字符是可以接受的:

$ mkdir /tmp/'myfolder with spaces'
$ touch /tmp/'myfolder with spaces'/myfile.txt

$ myfolder='/tmp/myfolder with spaces'
$ myfolder=${myfolder// /?}               # replace spaces with literal '?'
$ typeset -p myfolder
declare -- myfolder="/tmp/myfolder?with?spaces"

$ set -xv
$ ls $myfolder
+ ls '/tmp/myfolder with spaces'
myfile.txt

这是fiddle

当然,? 将匹配任何单个字符,但您有多个名称相似的目录/文件的可能性有多大,唯一的区别是空格与非空格?

【讨论】:

  • 谢谢你,@markp-fuso,为此。似乎没有更简单的内置方法可以在 bash 中执行此操作,但是由于这在技术上确实回答了我的问题,因此我将其标记为已接受的答案。它适用于我当前的用例,因为我不会有多个匹配项。巧妙地使用问号和字符替换——谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 1970-01-01
  • 2018-09-02
  • 2013-05-18
  • 1970-01-01
  • 2013-09-10
相关资源
最近更新 更多