All files in one directory, linux

Today I tried a script on Linux to get all the files in one directory. It was pretty simple, but I found something interesting.

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

Output:

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

But when I'm just entering the directory directly, for example:

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

Output:

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

It seems that in the first script there was only one loop, and all the file names were stored in the $ file variable in the FIRST loop, separated by a space. But in the second script, one file name was written to $ file in only one cycle and there were more than one cycle. What is the difference between these two scenarios?

Thanks a lot, maybe my question is a bit naive.

+4
source share
2 answers

The behavior is correct and "as expected."

for file in $InputDir'*' means assign "/home/XXX/*" to $file (note the quotation marks). Since you indicated an asterisk, it will not be executed at this time. When the shell sees echo $file , it first expands the variables, and then extends glob. So after the first step he sees

 echo /home/XXX/* 

and after glob extension he sees:

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

Only now will he execute the command.

In the second case, the template /home/XXX/* expanded before execution of for and, therefore, each file in the directory is assigned to file , and then the loop body is executed.

This will work:

 for file in "$InputDir"* 

but it is fragile; it will not work, for example, when you forget to add / to the end of the $InputDir variable.

 for file in "$InputDir"/* 

slightly better (Unix will ignore double slashes in the path), but this can cause problems when $InputDir not installed or empty: you will unexpectedly list files in the / (root) folder. This can happen, for example, due to a typo:

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

Unix Case :-)

To help you understand this code, use set -x ("enable tracing") in the line before the code you want to debug.

+8
source

The difference is quoting '*' . In the first case, the loop is executed only once, and $file is equal to /home/XXX/* , which then expands to all files in the directory when transferred to echo . In the second case, it is executed once for each file, while $file is equal to each file name.

The bottom line is the change:

 for file in $InputDir'*' 

in

 for file in $InputDir* 

or, better, and make it more readable - change:

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

in

 InputDir=/home/XXX for file in $InputDir/* 
+6
source

All Articles