#!/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:
findpath (content of $path)-typef(*.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=pathsupposed 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