4

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
1
  • 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. Jan 13, 2014 at 16:34

3 Answers 3

10

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' {} + )
3
  • 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, 2014 at 5:03
  • Moreover, I want a part of the path to the file hard coded.
    – user657592
    Jan 14, 2014 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, 2014 at 9:00
-1

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.

1
  • I tried your suggestion, but it does not seem to help.
    – user657592
    Jan 13, 2014 at 12:22
-1

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.

6
  • That doesn't change anything AFAICT: ls: cannot access sample/Fil*: No such file or directory.
    – l0b0
    Jan 13, 2014 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. Jan 13, 2014 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, 2014 at 13:03
  • @l0b0: not true, it works perfectly, just try it. Jan 13, 2014 at 13:07
  • @l0b0 I ran the code you see posted above, with call ./script.sh "tst*". Jan 13, 2014 at 13:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .