简体   繁体   中英

bash parameter expansion as arguments to command

I'm having difficulty trying to pass a bash parameter to find as arguments.

Best explained via code:

$ echo $BASH_VERSION
4.1.2(1)-release

$ find /etc -path '*/init.d' 2>/dev/null | wc -l
2

$ args="-path '*/init.d'"
$ echo $args
-path '*/init.d'
$ find /etc $args 2>/dev/null | wc -l
0

$ set -x; !!
set -x; find /etc $args 2>/dev/null | wc -l
+ wc -l
+ find /etc -path ''\''*/init.d'\'''
0

Where are the extra '' quotes coming from in the set -x output?

I've tried a number of different ways to get this to work but haven't had success so far. This guide seems to indicate that this should be possible, since parameter expansion takes place before command execution: http://stuff.lhunath.com/parser.png

Use an array:

args=( -path '*/init.d' )
find /etc "${args[@]}"

The reason the other approach doesn't work is discussed in detail in BashFAQ #50 . In short: Quote characters are handled during syntax parsing -- before parameter expansion occurs. Thus, when quote characters come from parameter expansion, they're not parsed as syntax, but treated as any other data: Run through string-splitting and glob expansion, and passed through to the program being run.

The extra quotes/escaping in set -x output are just how the shell tells you that your primary quotes are data, distinguishing them from quotes that are present as syntax.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM