简体   繁体   中英

How can I “look behind” the bash command line argument expansion?

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?

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.

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.

EDIT: As a final remark, I'd like to point out that using single quotes is common practice in unix shells as a mean to prevent expansion. You should not fear doing the same with your own script.

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

One additional answers for people coming to this question only to find nothing helpful: Consider my solution for preventing wildcard expansion (globbing), here .

The crux of it were outlined in this related answer .

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.)

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