bitbug@lonewolf.sun.com (James Buster) (07/15/89)
It seems what is desired is a variable that toggles globbing between one of two behaviors: The result of a globbing operation that fails causes the shell to return the filename substitution pattern, rather than an error, if the pattern is not matched, i.e. sh> echo *.d *.d sh> *or* a globbing operation that fails causes the shell to print a diagnostic and stop processing the current command or script, i.e. csh> echo *.d echo: No match. csh> Being able to toggle this behavior is, I believe, a desirable thing. The first style of behavior should probably be the default, but for those who want the shell to warn them of errors, the second could be done by setting a variable, such as `nomatch'. Note that 4.3 csh uses the `nonomatch' variable to cause the first style of behavior to occur. -- -------------------------------------------- James Buster Mad Hacker Extraordinaire bitbug@lonewolf.sun.com sun.com!lonewolf!bitbug --------------------------------------------
nickson@comp.vuw.ac.nz (Ray Nickson) (07/16/89)
Date: 14 Jul 89 19:15:02 GMT From: bitbug@sun.COM Subject: File Name Globbing It seems what is desired is a variable that toggles globbing between one of two behaviors: The result of a globbing operation that fails causes the shell to return the filename substitution pattern, rather than an error, if the pattern is not matched, i.e. ... *or* a globbing operation that fails causes the shell to print a diagnostic and stop processing the current command or script, i.e. ... All right, time for me to stick my neck out again. The patch at the end implements behaviour that is almost this; I despise csh's `No Match' whingeing so much that I refuse to make an empty glob an error. If this causes some scripts to hang reading stdin, then you bought it, you pay for it. This patch should be considered experimental; I don't intend to put it into the installed bash here. While I like the idea, I'm unhappy that I had to change the globbing semantics to such an extent to make this work comfortably; in particular, I've hacked gloobing so that the first word of a command is _never_ globbed. I can't think why anyone would want the first word globbed, but still... The reason I did this was that `[' is a perfectly valid (and oft-used) command; perhaps the best solution is to say that invalid (as opposed to empty) globbing characters should be left as is. Discussion? Anyway, here's the patch; take it or leave it. It gives current behaviour when nullglobok is unset, and allows empty globs if it's set. -rgn -- nickson@comp.vuw.ac.nz ...!uunet!vuwcomp!nickson + 64 4 721000x8593 PS: I intend to complete one more bash-hack, then revert to writing my thesis for a week or so... :-) --------------------cut here-------------------- *** subst.c.orig Thu Jun 29 15:38:23 1989 --- subst.c Sun Jul 16 13:47:59 1989 *************** *** 1227,1232 **** --- 1227,1235 ---- return (expand_words_1 (list, 0)); } + /* do we accept null globs, or refuse to glob? */ + int nullglobok = 0; + /* The workhorse for expand_words () and expand_words_no_var (). First arg is LIST, a WORD_LIST of words. Second arg DO_VARS is non-zero if you want to do environment and *************** *** 1315,1321 **** WORD_LIST *glob_list; orig_list = (WORD_LIST *)NULL; ! tlist = new_list; if (!disallow_filename_globbing) { --- 1318,1325 ---- WORD_LIST *glob_list; orig_list = (WORD_LIST *)NULL; ! tlist = new_list && nullglobok ? new_list->next : new_list; ! /* nullglobok: chop off word 0 so it doesn't get globbed */ if (!disallow_filename_globbing) { *************** *** 1362,1369 **** if (glob_list) orig_list = (WORD_LIST *)list_append (glob_list, orig_list); ! else ! orig_list = make_word_list (copy_word (tlist->word), orig_list); } else { --- 1366,1374 ---- if (glob_list) orig_list = (WORD_LIST *)list_append (glob_list, orig_list); ! else if (!nullglobok) ! orig_list = ! make_word_list (copy_word (tlist->word), orig_list); } else { *************** *** 1379,1384 **** --- 1384,1394 ---- tlist = tlist->next; } + /* nullglobok: patch word 0 back on */ + if (nullglobok) + orig_list = (WORD_LIST *) + list_append (orig_list, + make_word_list (copy_word (new_list->word), 0)); dispose_words (new_list); new_list = orig_list; } *************** *** 1428,1434 **** /* Not really `extern' just `forward'. */ extern int sv_path (), sv_mail (), sv_terminal (), sv_histsize (), sv_uids (), sv_ignoreeof (), sv_glob_dot_filenames (), sv_histchars (), sv_nolinks (), ! sv_hostname_completion_file (); #ifndef NOJOBS extern int sv_notify (); --- 1438,1444 ---- /* Not really `extern' just `forward'. */ extern int sv_path (), sv_mail (), sv_terminal (), sv_histsize (), sv_uids (), sv_ignoreeof (), sv_glob_dot_filenames (), sv_histchars (), sv_nolinks (), ! sv_hostname_completion_file (), sv_nullglobok (); #ifndef NOJOBS extern int sv_notify (); *************** *** 1456,1461 **** --- 1466,1472 ---- { "histchars", sv_histchars }, { "nolinks", sv_nolinks }, { "hostname_completion_file", sv_hostname_completion_file }, + { "nullglobok", sv_nullglobok }, { (char *)0x00, (Function *)0x00 } }; *************** *** 1475,1480 **** --- 1486,1499 ---- } i++; } + } + + /* what to do just after the nullglobok variable has changed */ + sv_nullglobok () + { + extern int nullglobok; + + nullglobok = (find_variable ("nullglobok") != 0); } /* What to do just after the PATH variable has changed. */
Ray Nickson <nickson@comp.vuw.ac.nz> (07/17/89)
All right, time for me to stick my neck out again. The patch at the end implements behaviour that is almost this; I despise csh's `No Match' whining so much that I refuse to make an empty glob an error. If this causes some scripts to hang reading stdin, then you bought it, you pay for it. This patch should be considered experimental; I don't intend to put it into the installed bash here. While I like the idea, I'm unhappy that I had to change the globbing semantics to such an extent to make this work comfortably; in particular, I've hacked gloobing so that the first word of a command is _never_ globbed. I can't think why anyone would want the first word globbed, but still... The reason I did this was that `[' is a perfectly valid (and oft-used) command; perhaps the best solution is to say that invalid (as opposed to empty) globbing characters should be left as is. Discussion? 1) Your patch closely matches mine, excepting two things. The first is the name of the variable; I used "allow_null_glob_expansion". The second is the excepting the first word of the command. I didn't do this, mostly because it didn't occur to me. But it brings up an interesting point. You asked when someone would use globbing characters in a command. The answer is: whenever they thought it would ease typing, just as in any other situation. Perhaps the name of the command to run in the current directory is "please_run_this_command". In that case, "ple*nd" will run that command, and will have saved the user much typing. 2) You say the reason that you didn't expand the first word is because you know of a command that contains a globbing character. Well, this is a much better argument for Bourne shell behaviour than any other I have thought of, since the first word of a command is not the only place you will see a globbing character. In the "if" command is another place. As the second word in an "eval" command is another place. Brian Fox
bart@videovax.tv.Tek.com (Bart Massey) (07/19/89)
In article <8907170737.AA04585@aurel.caltech.edu> bfox@aurel.caltech.edu.date.sun, 16 Jul 89 14:05:56 +1200 From: Ray Nickson <nickson@comp.vuw.ac.nz> writes: > > 2) You say the reason that you didn't expand the first word is because > you know of a command that contains a globbing character. Well, this > is a much better argument for Bourne shell behaviour than any other I > have thought of, since the first word of a command is not the only > place you will see a globbing character. In the "if" command is > another place. As the second word in an "eval" command is another > place. Agreed. However, the earlier poster's suggestion that invalid globs not expand should fix the problem. E.g. '[a-z' is a literal string, but '[a-z]' is a regexp. Note that all such "invalid" cases must involve the characters '[' or ']', since this is the only Bourne Shell globbing syntax which uses more than one character. Since '[' (a.k.a. 'set') is the only command I can think of or find on my machine which even potentially causes globbing problems, IMHO the above semantic should be more than adequate... I have a piece of really slow, recursive match, Bourne Shell style globbing code I wrote myself in C which implements the above semantic -- you're welcome to it if you're interested. Bart Massey ..tektronix!videovax.tv.tek.com!bart ..tektronix!reed.bitnet!bart