2

In my code , there is such a part ;

Namefile=$1
for n in $Namefile*
do
echo $n
done

and just for this part's result is ;

$ sh example.sh hw1
hw1_evening_sun.txt
hw1_morning_sun.txt
hw1_out_si_wire.txt
hw1_script.sh
hw1_script2.sh
hw1_script3.sh
hw1_sun1.txt
hw1_sun2.txt

which are the files whose name starting with "hw1" , but I don't understand why $Namefile* takes these names.As far as I know * calls the the argument which the script receives.

Why does this method work like that ? Could someone explain the logic behind it ?

5
  • Nope, * expands, You must be giving hw1 as it's first parameter; Otherwise the pwd at that moment would be containg files all of which starting with hw1. Commented Jun 3, 2016 at 5:45
  • Yes , you are right .I forgot to add the input. Commented Jun 3, 2016 at 5:52
  • That behavior is normal since you are saying hw1* if you need the parameters you have to use $* for debugging purposes you can use the set -x Commented Jun 3, 2016 at 6:26
  • İf it won't be a problem , could you briefly explain "set -x" part ? Commented Jun 3, 2016 at 6:27
  • 1
    set -x will expand the results of every line in your she'll script, sorry for being so late I'm on the road Commented Jun 4, 2016 at 13:00

4 Answers 4

1

I don't understand why $Namefile* takes these names.As far as I know * calls the the argument which the script receives.

$Namefile expands to the value that you passed in (probably "hw"). This means that $Namefile* after variable expansion becomes "hw*".

When this string is used in a location where it is interpreted as a filename, the * is special. See "pathname expansion" in the man page.

... bash scans each word for the characters *, ?, and [. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern.

2
1

Here you are doing a substitution in you for loop. So star will match every character after $Namefile string (which I guess it is "hw1"). If you want to match all the arguments provided to the script use the internal variable $*. In your script you are saving $1 (positional parameter number 1) which is wh1 to the variable Namefile. So using * after $Namefile has a different meaning than $*. For more info see here Internal Variables (Positional Parameters section)

6
  • I've already said what you say in the question.The problem is why it does that ? In definition $* must take the receiving statements not the file names. Commented Jun 3, 2016 at 6:02
  • 1
    Notice that $* is not the same as $Namefile*! Commented Jun 3, 2016 at 6:11
  • But still doesn't answer my question. Commented Jun 3, 2016 at 6:15
  • I think it should be clear now. Which part of the answer is not clear? Commented Jun 3, 2016 at 6:20
  • So , how does hw1* call the file names which start with hw1 just by itself ? Commented Jun 3, 2016 at 6:25
0

It's simply because of -l option of ls. In this case, because $Namefile* would expand to hw1_evening_sun.txt ..snip.. hw1_sun2.txt:

ls -l $Namefile*

is effectively equals to

ls -l hw1_evening_sun.txt ..snip.. hw1_sun2.txt

For more information, you can run man ls. Here I quote:

...  
   -l     use a long listing format  
...

Welcome to *nix.

2
  • But as I said in question , I am asking why $Namefile* take these values without ls -l $Namefile. Commented Jun 3, 2016 at 4:58
  • @Leth because the shell expands wildcards, not ls. Commented Jun 4, 2016 at 10:34
0

It is because your do loop is so. For the output to be as expected for -l you would need to execute your that part of script inside the backticks as below.


tmp.sh

Namefile=$1
for n in $Namefile*
do
echo $n
done

Run that particular part as,

ls -l `./tmp.sh "d"`

-bash-3.2$ ls -l `./again d`
-rw-r--r-- 1 me me 0 Jun  3 05:16 dat
-rw-r--r-- 1 me me 0 Jun  3 05:16 dis

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.