LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   bash asterisk variable substitution (https://www.linuxquestions.org/questions/linux-software-2/bash-asterisk-variable-substitution-703199/)

bt101 02-08-2009 04:50 PM

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.

raskin 02-08-2009 05:16 PM

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[@]}"

bt101 02-08-2009 05:52 PM

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.

raskin 02-08-2009 11:37 PM

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 06:44 AM.