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

pen*_*926 4 linux bash

今天我在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中,并且有多个循环.这两个脚本之间究竟有什么区别?

非常感谢,也许我的问题有点幼稚..

Aar*_*lla 8

行为是正确的,"正如预期的那样".

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的代码,请在要调试的代码之前的行中使用("启用跟踪").

  • 关于"`for file in"$ InputDir"*`:( ...)它会失败,例如,当你忘记添加一个`/`"时:你通常仍然可以把斜杠:`for file in" $ InputDir"/*`:即使你在InputDir值的末尾添加了一个"/",它在大多数(所有?)系统上仍然是正确的/ path/to //这应该指向/ path/to/this(至少它在Linux上,以及我所知道的大多数Unix) (2认同)

Pau*_*l R 6

不同的是引用'*'.在第一种情况下,循环只执行一次,$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)