一个目录中的所有文件,linux

时间:2013-04-18 11:52:46

标签: linux bash

今天我在linux中尝试了一个脚本来获取一个目录中的所有文件。这很简单,但我找到了一些有趣的东西。

 #!/bin/bash
InputDir=/home/XXX/
for file in $InputDir'*'
do
  echo $file
done

输出结果为:

/home/XXX/fileA /home/XXX/fileB 

但是当我直接输入目录时,如:

 #!/bin/bash
InputDir=/home/XXX/
for file in /home/XXX/*
do
  echo $file
done

输出结果为:

/home/XXX/fileA
/home/XXX/fileB

似乎在第一个脚本中,只有一个循环,所有文件名都存储在FIRST循环中的变量$ file中,用空格分隔。但是在第二个脚本中,一个文件名只在一个循环中存储在$ file中,并且有多个循环。这两个脚本之间究竟有什么区别?

非常感谢,也许我的问题有点天真......

2 个答案:

答案 0 :(得分:8)

行为正确且“符合预期”。

for file in $InputDir'*'表示assign "/home/XXX/*" to $file(请注意引号)。由于您引用了星号,因此此时不会执行。当shell看到echo $file时,它首先展开变量,然后进行全局扩展。所以在第一步之后,它会看到

echo /home/XXX/*

在全球扩张之后,它会看到:

echo /home/XXX/fileA /home/XXX/fileB

只有现在,它才会执行命令。

在第二种情况下,模式/home/XXX/*在执行for之前展开,因此,目录中的每个文件都分配给file,然后循环的主体是执行。

这将有效:

for file in "$InputDir"*

但它很脆弱;例如,当您忘记在变量/的末尾添加$InputDir时,它将失败。

for file in "$InputDir"/*

稍微好一点(Unix会忽略路径中的双斜线)但是当$InputDir未设置或为空时它会导致麻烦:你会突然列出/(root)中的文件)文件夹。例如,由于输入错误,可能会发生这种情况:

inputDir=...
for file in "$InputDir"/*

Unix上的案例: - )

为了帮助您理解这样的代码,请在要调试的代码之前的行中使用set -x(“启用跟踪”)。

答案 1 :(得分:6)

区别在于'*'的引用。在第一种情况下,循环仅执行一次,$file等于/home/XXX/*,然后在传递给echo时扩展到目录中的所有文件。在第二种情况下,它每个文件执行一次,$file依次等于每个文件名。

底线 - 更改:

for file in $InputDir'*'

为:

for file in $InputDir*

或更好,并使其更具可读性 - 更改:

InputDir=/home/XXX/
for file in $InputDir'*'

为:

InputDir=/home/XXX
for file in $InputDir/*