Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
02-08-2009, 05:50 PM
|
#1
|
Member
Registered: Mar 2008
Posts: 61
Rep:
|
bash asterisk variable substitution
Hi
I want to pass a mask to a bash program and have the find-command use this mask. Of course the mask will contain asterisks and I'm going nuts trying to find a combination of characters that will work.
I'll skip by all the code and just show you what I'm finding when I type at the command prompt:
# cd /tmp
# mkdir dir1 dir2 dir3
# cd /home
# find /tmp
/tmp
/tmp/dir1
/tmp/dir2
/tmp/dir3
Looks good. Now let's call find with an undefined (blank) switch.
# find /tmp $switch_str
/tmp
/tmp/dir1
/tmp/dir2
/tmp/dir3
Looks good. Now let's call find with the name-switch.
# find /tmp -name "*2*"
/tmp/dir2
Looks good. Now let's define a mask variable and use it with the name-switch.
# mask='*2*'
# echo "$mask"
*2*
# find /tmp -name "$mask"
/tmp/dir2
Looks good. Now let's combine the mask and the switch. This is where I run into trouble.
# echo "$mask"
*2*
# switch_str="-name \"$mask\""
# echo "$switch_str"
-name "*2*"
# find /tmp $switch_str
Now I get zero results.
I also tried
# switch_str="-name '$mask'"
# echo "$mask"
-name '*2*'
# find /tmp $switch_str
Same thing, I get nothing. BTW - I don't understand why the variable 'mask' was expanded even though it was in single quotes. I thought single quotes prevent expansion. Anyway...
I don't understand it. When I echo the variables they look perfectly normal. You might notice that when I echo the variables, I put quotes around them. If I try and put quotes around them in the find command I get this:
# echo "$switch_str"
-name "*2*"
# find /tmp "$switch_str"
find: unknown predicate `-name "*2*"'
Just in case you're wondering what I'm trying to do in this script.
If a mask is passed to the script, then I define the switch_str script. If no mask is passed, then the switch_str script remains undefined. That way, I can put this switch_str variable on the find command and it should either perform the name function, or just do nothing as it is blank.
I could make 2 separate find commands and have an if statement to choose one or the other, but I have a bunch of switches and a bunch of find commands to handle. I would prefer one find command and have a bunch of switches that are either active or blank.
So I'm lost.
Any help would be appreciated, Thanks.
|
|
|
02-08-2009, 06:16 PM
|
#2
|
Senior Member
Registered: Sep 2005
Location: France
Distribution: approximately NixOS (http://nixos.org)
Posts: 1,900
Rep:
|
You have switch_str which contains literal asterisks. But when you pass it to the find unquoted, obviously asterisks are expanded. Try using shell arrays ..
declare -a arg
arg[0]="-name"
arg[1]="test*"
find "${arg[@]}"
Last edited by raskin; 02-08-2009 at 06:20 PM.
|
|
|
02-08-2009, 06:52 PM
|
#3
|
Member
Registered: Mar 2008
Posts: 61
Original Poster
Rep:
|
That worked great, thanks.
The array-thing is a whole new area of bash programming with which I was not familiar (until now).
I'm sure you're right about the asterisks expanding. I'm not looking for any further answer here (I'm good now), but I must remark that I'm still perplexed as to why the asterisks were expanding. If I echo the variable, it looks normal with no expansion. I can even put the entire find command with the switches and asterisks inside one variable, and it will run properly if I just type that variable at the command prompt. But if I try to just put the switch in a variable, something funny happens.
|
|
|
02-09-2009, 12:37 AM
|
#4
|
Senior Member
Registered: Sep 2005
Location: France
Distribution: approximately NixOS (http://nixos.org)
Posts: 1,900
Rep:
|
When you want to get a deeper understanding, you can read man bash (on expansions) and info bash. The general idea is following: there are some expansions that always occur if a string is in specific context.
echo "$mask" -> echo "*2*" (stop, as * is inside "")
echo *2* -> something2
echo $mask -> echo *2* -> something2 (as now * is not inside *)
echo *2* (stops right here)
Another question is argument count..
"a b" is one argument, while a b gets split into two arguments.
@ is an exception in a sense - when used as index it allows "-enclosed string to get expanded to multiple arguments.
|
|
|
All times are GMT -5. The time now is 02:12 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|