Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

The following is the script I am running

#$1 - Argument
declare IPATH="sample/"
declare F=$IPATH$1
echo $F
ls $F

The input is ./script.sh "Fil*"

The echo output is -

sample/Fil*

when I run the command ls sample/Fil* I get the required output - A list of files whose name begins with FIL and are in the sample folder as this -

sample/File  sample/File1  sample/File2

But the script throws the below exception. What am I doing wrong?

ls: sample/Fil*: No such file or directory ls: $IPATH: No such file or directory
share|improve this question
    
Something very strange is happening here. The ls: $IPATH: No such file or directory part of the error doesn't make any sense -- as the script is written, the ls command should never see $IPATH, that should've been replaced by its value long before it got near ls. Try adding set -x at the beginning to enable tracing, and see what that prints about how it's running. –  Gordon Davisson Jan 13 at 16:34

3 Answers 3

up vote 5 down vote accepted

Globs are not expanded in quotes. You can expand them within scripts, but it's really bad practice (What if someone had a file name containing * or ?? They wouldn't be able to use your script to manipulate it). Best practice is to quote all variable references within scripts, and to pass the actual paths to the scripts:

$ mkdir sample
$ touch sample/File1 sample/File2
$ cat script.sh 
#!/bin/sh
F="$1"
echo "$F"
ls "$F"
$ ./script.sh sample/Fil*
sample/File1
sample/File1

Or even better, loop over all the files:

$ cat script.sh 
#!/bin/sh
for path
do
    echo "$path"
    ls "$path"
done
$ ./script.sh sample/Fil*
sample/File1
sample/File1
sample/File2
sample/File2

If you want to hard code part of the path, you could use find to expand it:

while IFS= read -r -d '' -u 9 path
do
    ls -- "$path"
done 9< <( find "sample" -name "$1" -exec printf '%s\0' {} + )
share|improve this answer
    
I guess THIS is the problem. But, I need the wild card character. ''. Let us say that I KNOW that the file names don't contain a ''. But I don't wish to expand them in the script either. Is there no other way? –  user657592 Jan 14 at 5:03
    
Moreover, I want a part of the path to the file hard coded. –  user657592 Jan 14 at 5:06
    
You are calling the script with the glob, so all you'd need to do is to call it without quoting the glob. The shell will take care of expanding it, and as long as you quote it inside the script you should have no problems. –  l0b0 Jan 14 at 9:00

ls runs in a separated shell. On that shell, IPATH is not defined, since you have not exported it.

Change "declare" with "export" and it will work.

share|improve this answer
    
I tried your suggestion, but it does not seem to help. –  user657592 Jan 13 at 12:22

Take the declare keyword out and it will work. No need of typing in Bash:

   #!/bin/sh
   IPATH="sample/"
   F=$IPATH$1
   echo $F
   ls $F

This will work as you expect.

share|improve this answer
    
That doesn't change anything AFAICT: ls: cannot access sample/Fil*: No such file or directory. –  l0b0 Jan 13 at 12:57
    
@l0b0 Because it is incorrectly used: first, you are missing the -r/-f/-a... option, then you cannot use a variable in the statement, $IPATH$1. –  MariusMatutiae Jan 13 at 12:57
    
You don't have to use one of those options. Try declare -p | grep 'declare --'. IFS, HOSTNAME and others are declared without a type, which means they are simply strings. –  l0b0 Jan 13 at 13:03
    
@l0b0: not true, it works perfectly, just try it. –  MariusMatutiae Jan 13 at 13:07
    
@l0b0 I ran the code you see posted above, with call ./script.sh "tst*". –  MariusMatutiae Jan 13 at 13:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.