#!/bin/bash
pat="'*.ab' -o -name '*.bc'"
open="\("
close="\)"
path=path
find $path -type f $open -name $pat $close
Above code doesn't show any output for find. Do help
#!/bin/bash
pat="'*.ab' -o -name '*.bc'"
open="\("
close="\)"
path=path
find $path -type f $open -name $pat $close
Above code doesn't show any output for find. Do help
You're using the wrong type of variable, and forgetting to quote them.
Here, you need an array to store more than one argument:
#! /bin/bash -
pat=('*.ab' -o -name '*.bc')
open='('
close=')'
path=path
find "$path" -type f "$open" -name "${pat[@]}" "$close"
Note that it's a *.ab
and (
argument you want to pass to find
, not '*.ab'
or \(
. Those quotes and backslash are part of the shell syntax.
That's only if you wanted to build a shell command line, for instance to pass to eval
for the shell to evaluate it that you would do:
#! /bin/bash -
pat="'*.ab' -o -name '*.bc'"
open="\("
close="\)"
path=path
eval 'find "$path" -type f '"$open -name $pat $close"
For the shell to then evaluate:
find "$path" -type f \( -name '*.ab' -o -name '*.bc \)
Which as above results in find
being called with these arguments:
find
path
(content of $path
)-type
f
(
*.ab
-o
-name
*.bc
)
eval find "$path" \( $expression \)
works. That is, you need to eval
the string.
– go2null
Sep 14 '19 at 12:05
$expression
is not quoted and the expansion of $path
(as opposed to a literal "$path"
string) would be passed to eval
(making it a command injection vulnerability for arbitrary values of $path
). Note how I'm careful to pass "$path"
inside single quotes and $pat
inside double quotes.
– Stéphane Chazelas
Sep 14 '19 at 12:26
pat="'*.ab' -o -name '*.bc'"
find $path -type f $open -name $pat $close
This doesn't do what you want: the quotes within the variable pat
aren't taken as quotes, but as literal characters. After $pat
is expanded, it's wordsplit, resulting in the words '*.ab'
, -o
, -name
and '*.bc'
, with the single quotes still intact. So unless you have filenames with single quotes within them, this will not match.
path=path
This sets the variable path
to the literal string path
, but I suppose this was just a placeholder.
open="\("
close="\)"
These put literal backslashes in the variables, and find
should probably complain as it gets an argument of \(
. It's enough to quote the parenthesis once, so either open="("
or open=\(
If you need to build a list of expressions for find
, use a shell with arrays (Bash or almost anything but plain sh
):
args=()
args+=( -name "*.ab" )
args+=( -or -name "*.bc" )
find ... \( "${args[@]}" \)
Wrap the array-building in a loop as necessary.
Use straightforward approach (instead of playing with variables):
find $path -type f -name "*.ab" -o \( -name "*.bc" \)
path=path
supposed to do? – scai Jun 19 '17 at 08:54(
inside quotes. – Michael Homer Jun 19 '17 at 08:57$pat
. – Gilles 'SO- stop being evil' Jun 20 '17 at 22:18