How to get filename completion without variable expansion?
Hi, I have the following problem: (Environment or regular) variable FOO contains the path of existing directory "/foo". When I have a file "/foo/bar" in that directory and when I press TAB in the following commandline ('|' denoting the cursor position) $ cat $FOO/b| bash expands the commandline to $ cat /foo/bar | However, I would like to expand it to $ cat $FOO/bar | that is, keep the variable unexpanded, exactly as bash does not expand tilde characters during filename completion. Any chances to achieve that with some shell or readline option? Thanks and regards Jens
Re: converting array to string by quoting each element for eval
On Tue, Nov 15, 2011 at 07:46:14PM -0600, Peng Yu wrote: > No. My real example use getopt. **NEVER** use getopt(1). It is broken. It cannot be made to work correctly. Its entire design is flawed. HP-UX getopt(1) says: WARNINGS getopt option arguments must not be null strings nor contain embedded blanks. OpenBSD getopt(1) says: BUGS ... Arguments containing whitespace or embedded shell metacharacters generally will not survive intact; this looks easy to fix but isn't. You may safely use getopts (the builtin). Never getopt. > If I have each option in a separate > argument, I need to know all the possible arguments to find, which is > not a viable route. *Why* do you "need to know" them? What does that sentence even mean? Is it because you have some NON-FIND OPTIONS after those? Then why not use the same trick that find(1) itself uses? Use a sentinel argument to indicate the end of the find-ish arguments. ';' would be nicely traditional. Better still would be to rearrange the invocation so that the arbitrary number of find-ish arguments are all at the end. > How to pass the option "-type f -name '*'" correctly? As four individual arguments, of course! ./myscript . -type f -name '*' > /tmp$ ./not_convert_args_to_string.sh . "-type f -name '*'" ^^^ NOT THAT. Please reread everything Chris said to you, because it all looked correct to me. If you *truly* need to serialize an array into a string and then retrieve it back into an array later, there are ways to do this, but you have not actually demonstrated a reason *why* you would ever need such a thing. All you've shown so far is a constantly mutating vagueness in which you keep trolling for some way to come up with a question which will convince someone to tell you how to do something you shouldn't be doing.
Re: converting array to string by quoting each element for eval
Hi Greg, > **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) (This is version of getopt on macports and ubuntu is free, I don't see there is a reason that getopt can not be ported to the two systems that you mentioned). All I see that is relevant is the following. I don't think that just because that it has a BUGS section in the manpage, it can be called broken. man bash also has BUGS section, is bash considered as broken? BUGS getopt(3) can parse long options with optional arguments that are given an empty optional argument (but can not do this for short options). This getopt(1) treats optional arguments that are empty as if they were not present. The syntax if you do not want any short option variables at all is not very intuitive (you have to set them explicitely to the empty string). AUTHOR Frodo Looijaard Note that it doesn't mean that I am resistant to getopts. It is just that I don't think that your logic is valid. But I will read more about getopts to see if it is necessary to convert from getopt to getopts. > ./myscript . -type f -name '*' 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 '*" -- Regards, Peng
Re: converting array to string by quoting each element for eval
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: <-maxdepth> <1> <-type> <-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
> And that is enough of this nonsense. I have cited three official manuals > for you already. Let's move on. I don't get it. Do you mean both traditional getopt and Debian getopt are broken. To me it seems that Debian getopt is made to address the short coming of transitional getopt. Yet you still think Debian getopt is broken? > Now that we know the goal, it's simple enough: No. That is not my goal. It is just a simplification of my goal. It is really hard to enumerate all the possible use cases, but I will try. In additional to the use cases I stated in the previous email, let's consider some more: ./myscript 'a b' 'c d' -o output.txt -type f -name '*' or ./myscript 'a b' 'c d' -output output.txt -type f -name '*' or ./myscript -output output.txt -type f -name '*' 'a b' 'c d' or ./myscript -type f -name '*' 'a b' -output output.txt 'c d' is equivalent find 'a b' 'a d' -maxdepth 1 -type f -name '*' > output.txt -- Regards, Peng
Re: converting array to string by quoting each element for eval
> You may safely use getopts (the builtin). Never getopt. If my understanding is correct, 'getopts' doesn't support the long format. Hence, it does not satisfy my need and I shall not use it. -- Regards, Peng