[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: converting array to string by quoting each element for eval
From: |
Greg Wooledge |
Subject: |
Re: converting array to string by quoting each element for eval |
Date: |
Wed, 16 Nov 2011 09:22:01 -0500 |
User-agent: |
Mutt/1.4.2.3i |
On Wed, Nov 16, 2011 at 08:05:03AM -0600, Peng Yu wrote:
> > **NEVER** use getopt(1). It is broken. It cannot be made to work
> > correctly. Its entire design is flawed.
>
> I don't see these warnings in my systems (macports and ubuntu)
Debian getopt(1) says:
Traditional implementations of getopt(1) are unable to cope with white-
space and other (shell-specific) special characters in arguments and
non-option parameters. To solve this problem, this implementation can
generate quoted output which must once again be interpreted by the
shell (usually by using the eval command). This has the effect of pre-
serving those characters, but you must call getopt in a way that is no
longer compatible with other versions (the second or third format in
the SYNOPSIS). To determine whether this enhanced version of getopt(1)
is installed, a special test option (-T) can be used.
And that is enough of this nonsense. I have cited three official manuals
for you already. Let's move on.
> To support your claim, tell me what myscript would be if the commands
>
> ./myscript 'a b' 'c d' -type f -name '*"
> ./myscript 'a b' -type f -name '*"
>
> actually do
>
> find 'a b' 'a d' -maxdepth 1 -type f -name '*"
> find 'a b' -maxdepth 1 -type f -name '*"
You have a double-quote at the end of each line. I will assume this is
a typo which was cut-and-pasted several times, and that you actually want
this invocation:
./myscript 'a b' 'c d' -type f -name '*'
to have this effect:
find 'a b' 'a d' -maxdepth 1 -type f -name '*'
Or in other words, you want to write a wrapper script which accepts
find(1) arguments but inserts the arguments -maxdepth 1 after the last
pathname.
Now that we know the goal, it's simple enough:
#!/bin/bash
paths=() i=0
while [[ $1 != -* ]]; do
paths[i++]=$1; shift
done
exec find "${paths[@]}" -maxdepth 1 "$@"
For testing purposes, I will replace "find" with "args", which is a
script I use to dump arguments to stdout so I can see them.
imadev:~$ ./foo 'a b' 'c d' -type f -name '*'
8 args: <a b> <c d> <-maxdepth> <1> <-type> <f> <-name> <*>
This appears to work correctly, assuming I understand what your goal is.
Here is ~/bin/args:
#! /bin/sh
printf "%d args:" $#
printf " <%s>" "$@"
echo
- Re: converting array to string by quoting each element for eval, (continued)
- Re: converting array to string by quoting each element for eval, Chris F.A. Johnson, 2011/11/15
- Re: converting array to string by quoting each element for eval, Peng Yu, 2011/11/15
- Re: converting array to string by quoting each element for eval, Chris F.A. Johnson, 2011/11/15
- Re: converting array to string by quoting each element for eval, Peng Yu, 2011/11/15
- Re: converting array to string by quoting each element for eval, Chris F.A. Johnson, 2011/11/15
- Re: converting array to string by quoting each element for eval, Peng Yu, 2011/11/15
- Re: converting array to string by quoting each element for eval, Chris F.A. Johnson, 2011/11/15
- Re: converting array to string by quoting each element for eval, Peng Yu, 2011/11/15
- Re: converting array to string by quoting each element for eval, Greg Wooledge, 2011/11/16
- Re: converting array to string by quoting each element for eval, Peng Yu, 2011/11/16
- Re: converting array to string by quoting each element for eval,
Greg Wooledge <=
- Re: converting array to string by quoting each element for eval, Peng Yu, 2011/11/16
- Re: converting array to string by quoting each element for eval, Peng Yu, 2011/11/16