#Macaroni (shells)
28 messages in this thread
You're definitely right on 2 things, that all the commands that avail
themselves of the "wildcard function call" will all have the same library call
and that a shell expansion provides a consistent user interface. The relation
between the function call overhead and the actual working code size of the
program would be minimal and therefore, in my book, negligible. If a system
function call is available (if you want to consider ARP part of the OS) then it
provides the same consistency as the shell expansion.
As far as whether you prefer shell expansion or an explicit library call, it
seems to be six of one and a half dozen of the other as far as I can tell. I
seem to prefer the function call on a matter of principle (the command having
control over its own command line format), but in real life I can't think of an
example to decide the issue one way or the other. This is, of course,
considering ARP as part of the standard system, which it isn't "out of the
box". The standard AmigaDOS commands are goners in this regard.
Doesn't shell expansion require the shell to find ALL the matches to a pattern
before calling the executable? If so, I find that not acceptable as I don't
want to spend the time waiting for the shell to load an entire directory (or
several of them) if I'm going to do a CTRL-C soon after the command starts
running through the list of files.
Martin,
Either the shell has to do it…or the program has to do it. There's
nothing stopping the shell from responding to a ^C.
Don
Yeah, but I often do DELETE #? and hit CTRL-C at a specific point. I guess I
could also do this with shell expansion, except I would have to wait for the
shell to first get all the names from the directory and then wait for DELETE to
start deletng and then kill it when it reaches the point were I'd like it to
stop.
Hmm, about this for a nifty solution. When the user specifies wildcards, the
shell redirects the input of the program to a pipe and then feeds the expanded
names in this pipe. Of course, thie requires the shell to be a separate
process, but it should work.
"Yes, but I often do DELETE #? and hit CTRL-C at a specific point."
Whew, you have more guts than I do, my friend!
Rick
Martin,
Why build a pipe when the command line will do? Shell expansion turns
this:
delete #?
into this:
delete filea fileb filec filed….
The delete command still reads the file names one at a time and deletes
the file and echoes it to the screen (presuming you don't do it in quiet mode).
Exactly the same as it does now except that the program reads the directory
structure rather than the shell.
Don
Yeah, but the shell has to get ALL the names from the directory prior to the
programs starting to do their stuff, that's the part I don't like. For example,
with ARP using the CMP (compare) program, I can do
CMP #? df1:#? Which checks all the files and reports different files. If I'm
only interested in the first file that's different, I hit CTRL-C as soon as CMP
indicates that there's a difference. Now with shell expansion, I would have to
wait for the shell to get ALL the filenames from the disk, and then CMP starts
to work, and then I can hit CTRL-C. This can take a loong time, especially if
you use the ALL switch.
Martin,
I agree.. there are times that expansion by the shell can get in the way. We're
working on a new shell for OS9, and one of the things we've done is allow a
switch (-w) at the beginning of a line to stop expansion. You could of course
also quote the ? * chars, but this provides another method. I like the choice.
Martin,
I certainly don't know what the ARP program does, but I'd guess it also
gets all it's names first. It then goes thru them one at a time. I still see
no difference.
Don
It takes TIME to scan a directory!! You have to WAIT for the shell to read the
COMPLETE directory before the command starts to work. THAT's the difference!
Martin,
And you think the program (presuming wildcard expansion is under
program control) doesn't have to read the whole directory? While it may be
able to work after it's found the first matching entry…rather than all
matching entries…by the time the program is completed, the time to find files
matching the wildcard criteria should be exactly the same using either method.
Don
Yes, that's true Martin, and the alternative is to have each command parse the
command line itself, resulting in excess baggage within each command, the more
detailed the parser, the more the baggage. In addition, we end up with a real
hodge-podge of parsers, some of which have options before the filename, some
after, inconsistencies like OPT A and ALL, and so on.
The advantages of the pre-parsed command line are overwhelming. You soon learn
to be a little more selective in your use of wildcards, and gain consistency
and power.
Take a look at the average Amiga command. Heck, most of them won't even allow
stdin or stdout to be defaluted, so we can pipe stuff to 'em.
-larry
Oh and isn't there a memory consideration in there? WHat if I do:
CMP dh0:dir1/dir2/dir3/dir4/#? ALL
Doesn't that un the chance of creating a list of filenames 10K long?
Martin,
As long as you use wildcards…you'll get a lot of filenames,the
program then sorts them into the desired items.
Look at it this way…you want to compare all the files on drive 1 with
all the files on drive 2. You'll end up with too many arguments, big deal, you
just script it to do a directory at a time. That's what I do under UNIX (where
the shell does the filename expansion)..it's no big deal. It's just slightly
different than what you're doing now…and it's uniform.
Don
Well I guess we disagree. If C= would have provided a standard pattern matching
routine from the start, as they ar planning for 1.4, then most, if not all
software would have also been uniform, without the restrictions imposed by
shell expansion.
Martin,
And because it's not uniform now…does that mean it can never be
uniform? That's all I'm asking for…uniformity. I believe that's best
obtained by having shell expansion because that's the way it's done in the
majority of shells that I'm familiar with (including the UNIX shells) and thus
it's less of a problem porting code from one environment to another.
I also see it as simplyfing code…it's much easier to handle the
argument count and loop based on that than it is to check to see if any of the
input arguments contains a wildcard and then expand it and also have to handle
looping based on the final number of arugments.
If I see I've got 20 arguments to a command, I can easily handle that
whether the arguments were typed by the user, or the result of shell expansion.
Without shell expansion, I've got to first check each argument, see if there's
a wildcard, expand that particular argument into it's matches and then go into
the program logic based on the now possibly new count of arguments.
Don
As a big unix fan, there was a time I would have agreed with you, but the truth
is there are a lot of advantages to *not* having wildcard expansion done in the
shell. One of the biggest advantages is in the case of rm *, unix systems will
happily delete all the files in the current directory with that one, while a
command that performs its own wildcard expansion can ask you if you really want
to do that.
As far as the rest goes, with a decent shared library pattern matching routine,
most of the objections go away, program logic is still very simple, and hardly
larger if at all then the case for just groveling through the commands.
Martin and charlie really did an outstanding job on the arp wildcard functions,
you should check them out, I wish I had them on unix…
sdb
Scott,
UNIX was written by programmers, for themselves. As a result, they
presumed you wanted to do what you told the computer to do. You could easily
have the rm command ask you if you wanted to delete each and every file… it's
just that's a real pain.
I haven't tried ARP, but presume if you tell it to DELETE * (or DELETE
#? <whatever it's wildcard is)…it does exactly what the UNIX command
does…it deletes all files. AmigaDOS certainly doesn't ask you if that really
what you want to do…the only OS I know that does that is MS-DOS, and it's
brain damaged.
Don
There are no restrictions imposed by shell expansion. If there are
restrictions, they are imposed by the target program. Perhaps it can't handle
that many arguments, or was not designed with the shell in mind. In any case,
handling of wildcard expansion, if left to the shell, _does_ standardize the
resulting programs, makes them smaller, and so on, if the programmers are aware
of the format in which they get arguments.
Expansion in each program is an anachronism, best left to the dinosaurs.
Remember, there are more ways to pass arguments from a shell to a program than
in one string. You could, if it was implemented properly, get all the benefits
of shell expansion while having the results start coming out immediately.
-larry
Untrue, there are many restrictions imposed by shell expansion. Take the
case for mv (rename). You cannot do
mv *.c *.x
on unix systems and have it make any sense at all. The reason for this
is because the shell and not the command expand the arguments. In order
to do this on unix you must write a for loop which is not a lot of fun
to type in each time you want to do this.
Most of the old objections to having each command do its own wildcarding
go away with shared library code. It doesn't make the programs larger,
you still have consistant wildcarding conventions, since the same
subroutine does it all, and if the wildcard expansion code is changed,
you only need to change the library, not each command.
sdb
Scott,
Many shells impose restrictions on a command line, and your example only
serves to show that the shell you are referring to (one of the Unix shells),
does indeed impose restrictions. It does not follow that pre-parsing must be
implemented in such a way as to impose this restriction.
Having a shared library do the parsing is really no different from having a
shell do it, dependent of course on the implementation of the library, and what
the call does. ie. what happens if the command line you mentioned is passed to
the library routine? Surely there is no difference, since the arguments are
still parsed externally.
I can envision a number of ways to parse and pass the results to a program
that would allow just such a command line to be entered, and to be sent to the
user program in a consistent manner. I can also think of ways that would not
require the so-called standard method of the parser having to analyze the
entire range of wildcards before starting to send the results.
I could definitely agree with a shared library parser. It's just that I see
no difference at all.
-larry
Don,
Of course there is a problem with the shell's doing the wild-card expansion.
I can think of a couple of examples. The first one, which I used to get burned
with occasionally when I was using Csh, is the command-line length and/or
number-of-arguments limits. I know the Lattice startup code does have a finite
limit on the number of argv vectors allowed, and I used to exceed that limit
every once in a while.
The second problem that comes to mind is with something like the Arp version
of rename, where I can specify a wild-card pattern for both the source and
target names, in which case things would really get confused by shell
expansion.
…BobR
Bob,
"too many arguments" is no big deal, just break it down into smaller
subsets of what you want. I do it on the UNIX machines all the time.
ARP isn't an issue either…it's not standard. IF the shell had done
command line expansion..the ARP would have been built to handle it. If in the
future, the shell does command line expansion, then ARP can be changed to
handle it.
In fact, that's a particulary good reason for shell expansion. ARP
could use the '*' character to mean target == souce so that
copy #?.c *.save
would get the #?.c expanded by the shell, and the *.save would be
handled by the ARP command as 1 for 1 with the input arguments. The other
options would be to escape the wildcards so the shell doesn't expand:
copy #?.c \#\?.save
Don
Simply a matter of programming… you are speaking about implementation
details.
-larry
Larry,
True. Unfortunately, this programming is in reference to existing programs.
…BobR
Bob,
Not so… the discussion seems to be about whether or not _a shell_ should or
should not parse the command line vs having _a program_ parse them.
-larry
Jeff,
I prefer shell expansion for one simple reason…it's uniform. A
program merely needs to check for only 2 things:
1. stdin redirected (input from a pipe)
2. number of command line arguments
That way, wildcards are uniform also. Right now, there are programs
that use the Amiga wildcards, UNIX wildcards or ignore wildcards. With shell
expansion, you know immediately where the fault lies when a command can't
handle multiple arugments.
Don
True, what I was thinking of was shell dictatorship. My MS-DOS is showing, I
think.