今天我在linux中尝试了一个脚本来获取一个目录中的所有文件.这很简单,但我发现了一些有趣的东西.
#!/bin/bash
InputDir=/home/XXX/
for file in $InputDir'*'
do
echo $file
done
Run Code Online (Sandbox Code Playgroud)
输出是:
/home/XXX/fileA /home/XXX/fileB
Run Code Online (Sandbox Code Playgroud)
但是当我直接输入dir时,就像:
#!/bin/bash
InputDir=/home/XXX/
for file in /home/XXX/*
do
echo $file
done
Run Code Online (Sandbox Code Playgroud)
输出是:
/home/XXX/fileA
/home/XXX/fileB
Run Code Online (Sandbox Code Playgroud)
看来,在第一个脚本中,只有一个循环,所有文件名都存储在FIRST循环中的变量$ file中,用空格分隔.但是在第二个脚本中,一个文件名只在一个循环中存储在$ file中,并且有多个循环.这两个脚本之间究竟有什么区别?
非常感谢,也许我的问题有点幼稚..
行为是正确的,"正如预期的那样".
for file in $InputDir'*'意思是assign "/home/XXX/*" to $file(注意引号).由于您引用了星号,因此此时不会执行.当shell看到时echo $file,它首先展开变量,然后进行全局扩展.所以在第一步之后,它看到了
echo /home/XXX/*
Run Code Online (Sandbox Code Playgroud)
在全球扩张之后,它看到:
echo /home/XXX/fileA /home/XXX/fileB
Run Code Online (Sandbox Code Playgroud)
只有现在,它才会执行命令.
在第二种情况下,在执行/home/XXX/*之前扩展模式for,因此,分配目录中的每个文件file,然后执行循环体.
这将有效:
for file in "$InputDir"*
Run Code Online (Sandbox Code Playgroud)
但它很脆弱; 例如,当您忘记将/变量添加到变量的末尾时,它将失败$InputDir.
for file in "$InputDir"/*
Run Code Online (Sandbox Code Playgroud)
有点好(Unix会忽略路径中的双斜线)但是当$InputDir没有设置或为空时它会导致麻烦:你会突然列出/(root)文件夹中的文件.例如,由于拼写错误,可能会发生这种情况:
inputDir=...
for file in "$InputDir"/*
Run Code Online (Sandbox Code Playgroud)
关于Unix的案例:-)
为了帮助您理解这样set -x的代码,请在要调试的代码之前的行中使用("启用跟踪").
不同的是引用'*'.在第一种情况下,循环只执行一次,$file等于/home/XXX/*,然后在传递给目录时扩展到目录中的所有文件echo.在第二种情况下,它每个文件执行一次$file,依次等于每个文件名.
底线 - 改变:
for file in $InputDir'*'
Run Code Online (Sandbox Code Playgroud)
至:
for file in $InputDir*
Run Code Online (Sandbox Code Playgroud)
或者,更好,并使其更具可读性 - 更改:
InputDir=/home/XXX/
for file in $InputDir'*'
Run Code Online (Sandbox Code Playgroud)
至:
InputDir=/home/XXX
for file in $InputDir/*
Run Code Online (Sandbox Code Playgroud)