SamIAm
SamIAm

Reputation: 2491

Why can't I pass a directory as an argument to a for loop in bash?

I have a simple bash script, simple.sh, as follows:

#/usr/local/bin/bash
for i in $1
   do
       echo The current file is $i
   done

When I run it with the following argument:

./simple.sh /home/test/*

it would only print and list out the first file located in the directory.

However, if I change my simple.sh to:

#/usr/local/bin/bash
DIR=/home/test/*
for i in $DIR
   do
       echo The current file is $i
   done

it would correctly print out the files within the directory. Can someone help explain why the argument being passed is not showing the same result?

Upvotes: 11

Views: 15326

Answers (4)

chepner
chepner

Reputation: 531055

Your script does not receive "/home/test/*" as an argument; the shell expands the patter to the list of files that match, and your shell receives multiple arguments, one per matching file. Quoting the argument will work:

./simple.sh "/home/test/*"

Your change to using DIR=/home/test/* did what you expected because filename generation is not performed on the RHS of a variable assignment. When you left $DIR unquoted in the for loop, the pattern was expanded to the list of matching files.

Upvotes: 1

Jens
Jens

Reputation: 72639

This is as portable as it gets, has no useless forks to ls and runs with a minimum of CPU cycles wasted:

#!/bin/sh
cd $1
for i in *; do
   echo The current file is "$i"
done

Run as ./simple.sh /home/test

Upvotes: 2

Oni1
Oni1

Reputation: 1505

If you take "$1", it is the first file/directory, which is possible! You should do it in this way:

for i in "$@"
do
  echo The current file is ${i}
done

If you execute it with:

./simple.sh *

They list you all files of the actual dictionary

"$1" is alphabetical the first file/directory of your current directory, and in the for loop, the value of "i" would be e.g. a1.sh and then they would go out of the for loop! If you do:

DIR=/home/<s.th.>/* 

you save the value of all files/directories in DIR!

Upvotes: 12

Jintian DENG
Jintian DENG

Reputation: 3202

How about list the file manully instead of using *:

  #/usr/local/bin/bash
  for i in $(ls $1)
  do
      echo The current file is $i
  done

and type

 ./simple.sh /home/test/

Upvotes: -2

Related Questions