Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass a wildcard parameter to a bash file

I'm trying to write a bash script that allows the user to pass a directory path using wildcards.

For example,

bash show_files.sh * 

when executed within this directory

drw-r--r--  2 root root  4.0K Sep 18 11:33 dir_a -rw-r--r--  1 root root   223 Sep 18 11:33 file_b.txt -rw-rw-r--  1 root root   106 Oct 18 15:48 file_c.sql 

would output:

dir_a file_b.txt file_c.sql 

The way it is right now, it outputs:

dir_a 

contents of show_files.sh:

#!/bin/bash  dirs="$1"  for dir in $dirs do     echo $dir done 
like image 942
eisaacson Avatar asked Oct 18 '13 20:10

eisaacson


People also ask

Can you pass in an argument to a bash script?

You can pass the arguments to any bash script when it is executed. There are several simple and useful ways to pass arguments in a bash script. In this article guide, we will let you know about some very easy ways to pass and use arguments in your bash scripts.

What does * represent in bash?

It's a space separated string of all arguments. For example, if $1 is "hello" and $2 is "world", then $* is "hello world".


2 Answers

The parent shell, the one invoking bash show_files.sh *, expands the * for you.

In your script, you need to use:

for dir in "$@" do     echo "$dir" done 

The double quotes ensure that multiple spaces etc in file names are handled correctly.

See also How to iterate over arguments in a bash shell script.


Potentially confusing addendum

If you're truly sure you want to get the script to expand the *, you have to make sure that * is passed to the script (enclosed in quotes, as in the other answers), and then make sure it is expanded at the right point in the processing (which is not trivial). At that point, I'd use an array.

names=( $@ ) for file in "${names[@]}" do     echo "$file" done 

I don't often use $@ without the double quotes, but this is one time when it is more or less the correct thing to do. The tricky part is that it won't handle wild cards with spaces in very well.

Consider:

$ > "double  space.c" $ > "double  space.h" $ echo double\ \ space.? double  space.c double  space.h $ 

That works fine. But try passing that as a wild-card to the script and ... well, let's just say it gets to be tricky at that point.

If you want to extract $2 separately, then you can use:

names=( $1 ) for file in "${names[@]}" do     echo "$file" done # ... use $2 ... 
like image 88
Jonathan Leffler Avatar answered Oct 05 '22 14:10

Jonathan Leffler


Quote the wild-card:

bash show_files.sh '*' 

or make your script accept a list of arguments, not just one:

for dir in "$@" do     echo "$dir" done 

It's better to iterate directly over "$@' rather than assigning it to another variable, in order to preserve its special ability to hold elements that themselves contain whitespace.

like image 32
chepner Avatar answered Oct 05 '22 14:10

chepner