字符串连接为命令的参数

时间:2016-12-14 02:56:36

标签: bash shell

在bash shell中,我想在完整路径下列出$ folder(我的代码中的变量名)下的文件名。

但是,如果我这样编码,

dir $folder"*"

输出错误

"dir: cannot access <folder_name> : No such file or directory"

如果我更改这样的代码

,它会起作用
search_str=$folder"*"
dir $search_str 

似乎连接到dir命令的字符串不是我想要的,如果我将字符串存储在一个变量中并将其传递给dir命令就可以了。

任何人都知道原因&amp;怎么不使用search_str?

3 个答案:

答案 0 :(得分:5)

注意:我在下面的示例中使用的是标准Unix实用程序ls而不是GNU-specific utility dir(感谢hek2mgl),因为该问题与通用shell行为和不仅限于具有 GNU 实用程序的平台。

<强> TL;博士

ls "$folder"* # double-quote the var. reference, use * unquoted

*等模式(全局)元字符必须使用不加引号 才能被识别。

因此,ls $folder"*"总是按预期工作,因为您(双 - )引用了 *

相比之下,变量赋值search_str=$folder"*"会将*附加到$folder的值(作为文字,因为它是双引号,但最终没有引号,因为shell在字符串连接过程中删除了双引号,因为它们具有语法含义而不是文字;这种删除被恰当地调用引用删除)。

命令ls $search_str中变量的未加引号的使用然后使*有效作为通配符(模式元字符)。

然而,未加引号使用变量本质上是不健全 ,因为$search_str的值整体不仅要使用globbing,还要使用分词,这意味着如果原始$folder变量包含带有嵌入空格的路径,命令将会中断。

因此,当实际需要使用globbing时,最好追加* 按需

ls "$folder"*

请注意*未加引号的方式 - 使其作为模式元字符有效 - 而"$folder"有意双引号 - 以确保将用作 -is (分词和globbing不应用于其值)。

答案 1 :(得分:0)

假设$ folder是tmp dir $ folder&#34; *&#34;相当于dir tmp*

而在下面

的情况下
search_str=$folder"*"
dir $search_str 

$ search_str相当于dir temp

当您使用双引号时,需要额外的步骤才能展开。详细了解shell中的变量扩展

答案 2 :(得分:0)

虽然@ mklement0的答案解释了错误的原因,但您也可以寻找其他可能的解决方案。首先让我借用另一个回答下面的行

  

模式(globbing)元字符如*必须在未引用的情况下使用   为了得到承认。

案例1:如果您希望在文件夹中递归列出(不是解析,只列出)文件(仅限文件),请使用[ globstar ]

shopt -s globstar
folder="yourfoldername**"
ls -p $folder | grep -v '/$'   #mind that '$folder' is not inside double quotes
# '-p' adds trailing slash to directories and we neglect those results using grep invert match
# Here I inadvertantly parsed the `ls` output, see the link in case 2 for why  you shouldn't do that.

案例2:如果您希望在文件夹中递归地解析(不仅仅是列出)文件(仅文件),请使用find作为ls输出无法解析 [Check this]

folder="yourfoldername" #no trailing **
find "$folder" -type f -print0 | while read -r -d '' fname
do
#do something with "$fname"
done