tags:

views:

78

answers:

4

I want a Perl script to accept wildcards (foo-*.ba?) for file names (which are then processed for a whole directory subtree).

Of course, I can tell the users of my script to quote the argument ('foo-*.ba?'), but this is not really elegant - the wildcard method is meant as a user-friendly alternative to passing regexes (which are accepted, too, and which, of course, must be quoted). The trouble is, that the shell (bash, in my case) expands the command line to the files matching the wildcard pattern in the current directory, so my poor script gets @ARGV preset with whatever the bash found (typically nothing, or a bunch of foo-lotsof.baz etc.).

Is there a copy of bash's unexpanded command line anywhere?

+3  A: 

i'm afraid there is no simple way around this. bash expands wildcards before executing a command. that's why you have to quote parameters to find -name '*.txt'—if you don't bash will try to expand the wildcard and you get not the results you wanted

knittl
This is correct. The shell expands them before your program gets them, and you program has no way of knowing whether the input was expanded by the shell or typed as-is.
bta
You can also escape, as in `find -name \\*.txt`. But that won't make OP any happier.
Philippe A.
+2  A: 

Bash expands wildcards then passes them to the program. This is a feature of bash, and it's how bash works, so I don't think you'll be able to find a way around it. (Interestingly, Windows' command line shell does not expand wildcards, so you have to do somewhat painful workarounds to get Perl scripts to work as expected.)

Quoting filenames is the standard solution, and Linux command line users should be very familiar with it.

Other programs (such as find(1)) have the same issue of needing to quote arguments that take wildcards.

(Even if you could figure out some way to query bash's command line history from your Perl script to find the command as the user typed it, you'd still have problems with your script being run from other shells, other scripts, etc.)

Josh Kelley
+4  A: 

Please don't try to work around this. Changing how arguments are interpreted is done by the user in their choice of quoting. Even if you can (and I know there are hooks in bash that I know nothing about that may make it possible) you are not going to provide a better user experience this way, you will provide a worse.

ysth
+4  A: 

According to bash man page, you can disable expansion of characters *, ? and [ with the -f switch. See Pathname Expansion.

$ bash -f -c 'ls *'
ls: *: No such file or directory

But then you have to ask your users to change the way they start bash, or you have to try get control over this. It is simply shifting the problem around.

Your program should deal with the shell behavior, not the other way around.

Philippe A.