Open Letter / Suggestion for shells: Need access to original command line...

Open Letter / Suggestion for shells: Need access to original command line...

Post by Roy Ivy II » Sun, 22 Aug 1999 04:00:00



I propose that we add, in a standard way, access to the command line used to
initiate a program. The command line should have already had aliasing and
environment variable substitution done, but NOT have globbing or dequoting
done.

Here's why:
I've run into multiple problems when trying to port DOS/Win programs to UNIX
programs. There is just not enough flexibility in the UNIX systems about
command line parsing. The program never gets to interpret the command line
in a more complicated way if it's needed. UNIX hides all command line
processing before the program even gets to see the original command line.

Current problems:

1) Unable to differentiatiate "*.c" from \*.c , which is not really a
problems as both should be the same thing given current interpretations.
However, you can't differentiate -x from "-x". This causes tons of email
asking how to delete a file with a leading dash (-).

2) Null arguments for options can be lost: -foo: "" is different
from -foo:"" which loses the trailing quotes and therefore it's null
argument.

3) Target wildcards are not possible using normal command line syntax as it
stands now, i.e. 'cp *.c *.c.o' does not do what you intuitively expect. DOS
systems have had this for a few years (refer to #5).

4) DOS-style response files are difficult to implement because there is no


5) It would allow easier porting of applications between DOS/Win and UNIX
systems.

I propose that all standard shells store the command line after redirection,
subshell execution (i.e. echo `date`), aliasing, and environment variable
substitution (but BEFORE dequoting and globbing is done) in an environment
variable, $CMDLINE. There would be no change to the default command line
handling.

I think that a standard way to match and dissect matching symbols would be a
great boon to certain command line programs (and no detriment to programs
which just want the shell to do everything). All shells should make globbing
available as a library / system call. Globbing should be standard POSIX but
with the addition of optionally returning match locations of glob / wildcard
characters.

I recommend the set CMDLINE behavior be put in the GCC compiler so that
system, execXX. and spawnXX all set the CMDLINE variable when calling other
programs. This would probably automatically set it for shells compiled with
GCC. Or how about putting it in '$!cmdline' to avoid any possibility of
conflict.

Ideas? Comments? Criticisms?

- Roy Ivy III

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Ken Pizzi » Sun, 22 Aug 1999 04:00:00



Quote:>I propose that all standard shells store the command line after redirection,
>subshell execution (i.e. echo `date`), aliasing, and environment variable
>substitution (but BEFORE dequoting and globbing is done) in an environment
>variable, $CMDLINE. There would be no change to the default command line
>handling.
...
>I recommend the set CMDLINE behavior be put in the GCC compiler so that
>system, execXX. and spawnXX all set the CMDLINE variable when calling other
>programs. This would probably automatically set it for shells compiled with
>GCC. Or how about putting it in '$!cmdline' to avoid any possibility of
>conflict.

That placement won't work --- by the time you get down to
exec*() calls the command line has already be parsed down to
individual arguments by the shell.  In order to set CMDLINE in
the manner you desire, the shells themselves would need to be
modified.

                --Ken Pizzini

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Roy Ivy II » Sun, 22 Aug 1999 04:00:00





> >I propose that all standard shells store the command line after
redirection,
> >subshell execution (i.e. echo `date`), aliasing, and environment variable
> >substitution (but BEFORE dequoting and globbing is done) in an
environment
> >variable, $CMDLINE. There would be no change to the default command line
> >handling.
> ...
> >I recommend the set CMDLINE behavior be put in the GCC compiler so that
> >system, execXX. and spawnXX all set the CMDLINE variable when calling
other
> >programs. This would probably automatically set it for shells compiled
with
> >GCC. Or how about putting it in '$!cmdline' to avoid any possibility of
> >conflict.

> That placement won't work --- by the time you get down to
> exec*() calls the command line has already be parsed down to
> individual arguments by the shell.  In order to set CMDLINE in
> the manner you desire, the shells themselves would need to be
> modified.

Yes, I mentioned, in passing, something like that:

Quote:>I propose that all standard shells store the command line after
redirection,
>subshell execution (i.e. echo `date`), aliasing, and environment variable
>substitution (but BEFORE dequoting and globbing is done) in an environment
>variable, $CMDLINE. There would be no change to the default command line
>handling.

I realize the full solution would mean modification to all the standard
shells, but a change to the gcc library exex*(), etc. would enable some
partial solutions with minimal pain. And it might start the ball rolling for
a better full solution.

- Roy Ivy

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Ariel Scolnico » Mon, 23 Aug 1999 04:00:00



Quote:> I propose that we add, in a standard way, access to the command line used to
> initiate a program. The command line should have already had aliasing and
> environment variable substitution done, but NOT have globbing or dequoting
> done.

> Here's why:
> I've run into multiple problems when trying to port DOS/Win programs to UNIX
> programs. There is just not enough flexibility in the UNIX systems about
> command line parsing. The program never gets to interpret the command line
> in a more complicated way if it's needed. UNIX hides all command line
> processing before the program even gets to see the original command line.

> [...]

> Ideas? Comments? Criticisms?

Are you sure it's a good idea?  <flame> Currently, we have consistent
command-line behaviour.  This is a Good Thing.  Your suggestion could
be reasonable on a system where each command-line ran one command, the
arguments of which didn't depend on the other commands.  So "mv *.c
*.h" makes sense, apart from the horrible inconsistencies.  But if
that works, why doesn't

        mv `find . -name '*.c' -print` `find . -name '*.h' -print`

work?  It says, perfectly clearly, to rename all .c files below this
directory to .h files.  Or what about "mv **/*.c **/*.h", which should
do the same, but only if my shell is zsh?  (If I'm using tcsh and this
works, I'll get confused when "echo **/*.c" doesn't).

Now imagine what happens when people start using this feature.
Obviously, GNU getopt invariably uses it.  Anyone porting MS-DOS
programs to UNIX uses it to attain case insensitivity in filenames,
with one of 3 different libraries with subtly different globbing
rules.  People writing "mv" (or "find", which could automatically
quote the argument after "-name", or "grep") do their own thing with
wildcards, of course.  Quick question: what are the arguments to
"my-script -a *.[ch]"?  Come to think of it, what should "mv *.[ch]"
do?  What about "mv *.c *.i *.h"?  Most importantly, why should I have
to know the answers to all these things?

If anything, this should be done with shell aliases.  Even then, it's
a great way to lose friends and confuse your users.  Over here, our
standard environment says essentially

        alias foo ( set noglob;foo !*)"

for several commands foo, in order to do essentially what you
suggested (also in the name of "compatibility with MS-DOS").  Of
course, you can't know what this does, so I'll have to tell you: foo
does its own globbing, in a case-insensitive manner.  I once spent 30
minutes with someone trying to work out why her csh script wasn't
working, since neither of us knew about this awesome "feature".

The problem with UNIX globbing is that it has too many special cases,
not that it has too few.</flame>

--

Compugen Ltd.          |Tel: +972-2-6795059 (Jerusalem) \  NEW IMPROVED URL!
72 Pinhas Rosen St.    |Tel: +972-3-7658520 (Main office)`--------------------
Tel-Aviv 69512, ISRAEL |Fax: +972-3-7658555  http://3w.compugen.co.il/~ariels

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Victor Wagn » Mon, 23 Aug 1999 04:00:00



: I propose that we add, in a standard way, access to the command line used to
: initiate a program. The command line should have already had aliasing and
: environment variable substitution done, but NOT have globbing or dequoting
: done.

: Here's why:
: I've run into multiple problems when trying to port DOS/Win programs to UNIX
: programs. There is just not enough flexibility in the UNIX systems about
: command line parsing. The program never gets to interpret the command line

There is more than enough flexibility in Unix shell. You have just to
learn it.

: in a more complicated way if it's needed. UNIX hides all command line
: processing before the program even gets to see the original command line.

: Current problems:

: 1) Unable to differentiatiate "*.c" from \*.c , which is not really a
: problems as both should be the same thing given current interpretations.
: However, you can't differentiate -x from "-x". This causes tons of email
: asking how to delete a file with a leading dash (-).

rm ./-x

: 2) Null arguments for options can be lost: -foo: "" is different
: from -foo:"" which loses the trailing quotes and therefore it's null
: argument.

No comments.

: 3) Target wildcards are not possible using normal command line syntax as it
: stands now, i.e. 'cp *.c *.c.o' does not do what you intuitively expect. DOS
: systems have had this for a few years (refer to #5).

UNIX is not intuitive. It is logical. Which is much better.
I hate programs which try to behave intuitively, such as perl, becouse
every man has its own intuition, but logic is universal. It can be
precisely defined by finite amount of words and understood in finite
time.

: 4) DOS-style response files are difficult to implement because there is no


see 2.

: 5) It would allow easier porting of applications between DOS/Win and UNIX
: systems.

Name at least one application which deserves so. I know only few
archiviers, but all the file-handling code in them should be rewritten
from scratch anyway, to allow handling of links, attributes and other
features of Unix file systems which couldn't be found in DOS world.

I'm not considering GUI apps such as Corel Draw or Adobe PageMaker. Such
beasts obvoisly deserve porting, but they wouldn't have such a problems,
becouse they do not rely on command line parsing anyway.

: I propose that all standard shells store the command line after redirection,
: subshell execution (i.e. echo `date`), aliasing, and environment variable
: substitution (but BEFORE dequoting and globbing is done) in an environment
: variable, $CMDLINE. There would be no change to the default command line
: handling.

It is just impossible. Next time would like to access commandline just
after subshell, substitution, then just after aliasing etc etc etc.

And now I'm free to choose between

prog *.c and prog `find . -name "*c"`. If you suggestion is implemented,
this freedom would be lost. Each time when I need more sophisticated
filtering which standard globbing provides (and can be easily achieved
via find and grep) I would need to consider if my program is true unix
application, which doesn't care how its command line was constructed by
shell, or it is silly program ported from DOS which makes use o CMDLINE
variable.

: I think that a standard way to match and dissect matching symbols would be a
: great boon to certain command line programs (and no detriment to programs
: which just want the shell to do everything). All shells should make globbing
: available as a library / system call. Globbing should be standard POSIX but
: with the addition of optionally returning match locations of glob / wildcard
: characters.

glob is avaliable as library function, and I always prefer it to
opendir/readdir approach. But it has nothing to do with shells (except
that it might be used by them) Shell is just yet another program, which
have nothing special in it. And it is good, becouse it allows me to
choose one of several shells.

: I recommend the set CMDLINE behavior be put in the GCC compiler so that
: system, execXX. and spawnXX all set the CMDLINE variable when calling other

system calls a shell, so if shell sets CMDLINE, it would be set.

It is just impossible to set CMDLINE during exec, becouse exec recieves
completely processed arguments and doesn't perform any globbing or
dequoting. Thus your suggestion becomes even more pointless, becouse if
your program is called from another program via fork/exec, it recieves
only those arguments calling program choose to pass, and cannot even
hope any stages of processing, shell does, was really performed.

: programs. This would probably automatically set it for shells compiled with
: GCC. Or how about putting it in '$!cmdline' to avoid any possibility of
: conflict.

: Ideas? Comments? Criticisms?

There is russian saying "Don't go to other's monastery with own rules".
Please learn rules of new system you come into before suggesting to
change them.

: - Roy Ivy III

--
--------------------------------------------------------

I don't answer questions by private E-Mail from this address.

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Ken Pizzi » Mon, 23 Aug 1999 04:00:00



Quote:>> >I recommend the set CMDLINE behavior be put in the GCC compiler so that
>> >system, execXX. and spawnXX all set the CMDLINE variable when calling other
>> >programs. This would probably automatically set it for shells compiled with
>> >GCC. Or how about putting it in '$!cmdline' to avoid any possibility of
>> >conflict.

>> That placement won't work --- by the time you get down to
>> exec*() calls the command line has already be parsed down to
>> individual arguments by the shell.  In order to set CMDLINE in
>> the manner you desire, the shells themselves would need to be
>> modified.
>I realize the full solution would mean modification to all the standard
>shells, but a change to the gcc library exex*(), etc. would enable some
>partial solutions with minimal pain. And it might start the ball rolling for
>a better full solution.

I still fail to see how any modification to exec*() calls can
help --- all of the information (well, perhaps not the first
argument) that is passed to them are _already_ being fed to the
new process image.  The issue is getting more information passed
to the child, but exec*() simply is not privy to anything more.

                --Ken Pizzini

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Campbell, Rolf [SKY:1U32:EXCH » Tue, 24 Aug 1999 04:00:00




> [snip]
> # : 3) Target wildcards are not possible using normal command line syntax as it
> # : stands now, i.e. 'cp *.c *.c.o' does not do what you intuitively expect. DOS
> # : systems have had this for a few years (refer to #5).

> for name in *.c;do cp $name ${name}.o;done
> Simple, huh. ;)  Unix is easy if you take the time to learn.  Changing
> expected shell behaviour in Unix is nuts.  In my opinion.
> Most of your problems would be solved if you took the time to learn
> your shell.

What about "ren *.jpeg *.jpg"?  I'm not saying that I agree with what Roy Ivy
wrote, but I do use command-lines like that frequently, which are possible to do in
bash, but not easy.  The only way I can think of doing that is:

for name in *.jpeg
do
 mv $name `jpeg2jpg $name`
done

And make a program called jpeg2jpg which converted it's command-line parameter.
What I'm really looking for is a regular-expression 'mv' utility that would except
a command-line like:

mv "^\(.*\)\.jpeg" "\1.jpg"

--
     -Rolf Campbell (39)3-6318

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Chet Ram » Tue, 24 Aug 1999 04:00:00




Quote:>What about "ren *.jpeg *.jpg"?  I'm not saying that I agree with what Roy Ivy
>wrote, but I do use command-lines like that frequently, which are possible to do in
>bash, but not easy.  The only way I can think of doing that is:

>for name in *.jpeg
>do
> mv $name `jpeg2jpg $name`
>done

Use what the shell gives you.

        for name in *.jpeg
        do
                mv $name ${name/%jpeg/jpg}
        done

This could easily be packaged into a `rename-by-suffix' command.

Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
( ``Discere est Dolere'' -- chet)


 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Sweth Chandramou » Tue, 24 Aug 1999 04:00:00




Quote:>What about "ren *.jpeg *.jpg"?  I'm not saying that I agree with what Roy Ivy
>wrote, but I do use command-lines like that frequently, which are possible to
>do in
>bash, but not easy.  The only way I can think of doing that is:

>for name in *.jpeg
>do
> mv $name `jpeg2jpg $name`
>done

>And make a program called jpeg2jpg which converted it's command-line parameter.
>What I'm really looking for is a regular-expression 'mv' utility that would
>except
>a command-line like:

>mv "^\(.*\)\.jpeg" "\1.jpg"

        it exists, and is called ksh or any of its derivatives:

for FILE in *.jpeg ; do mv ${FILE} ${FILE%.jpeg}.jpg ; done

        trying to make a utility out of this sort of task is in
many ways ridiculous because the utility would have to have
hard-coded into it the algorithm used to do the filename
translation.  while an algorithm that matched the shell's
(very robust) wildcard syntax _could_ be created, it would
probably not be worth the effort; the other option is to do
what the dos version does, which is only implement a very
small level of wildcard matching.

        -- sweth.

--

<a href="http://astaroth.nit.gwu.edu/resume/">Will Work For Food.</a>
<a href="http://astaroth.nit.gwu.edu/~sweth/disc.html">*</a>

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Klaus Alexander Seistr » Tue, 24 Aug 1999 04:00:00



> What I'm really looking for is a regular-expression 'mv' utility
> that would except a command-line like:

> mv "^\(.*\)\.jpeg" "\1.jpg"

There is a utility called `mmv' that will let you do just that, I believe
it's available somewhere in comp.sources.{misc,unix}.  Or you can try and
click this URL and see if Google comes up with something useful:

  http://www.google.com/search?q=mmv

Cheers,

  //Klaus

--
[ Magnetic Ink ] ><>
[ http://www.magnetic-ink.dk/ ]

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Campbell, Rolf [SKY:1U32:EXCH » Tue, 24 Aug 1999 04:00:00



>         trying to make a utility out of this sort of task is in
> many ways ridiculous because the utility would have to have
> hard-coded into it the algorithm used to do the filename
> translation.  while an algorithm that matched the shell's
> (very robust) wildcard syntax _could_ be created, it would
> probably not be worth the effort; the other option is to do
> what the dos version does, which is only implement a very
> small level of wildcard matching.

    I wouldn't call ?*[] very robust wildcards.  I think full regular-expressions
would have been a better choice.  But, I don't think they should be changed.  It is
too easy to use somthing like egrep to make the functionality that bash is missing:

alias rls = "ls -l `ls -a1 | grep $1`"

I can't remember the exact syntax of alias, so what I've given is probably wrong,
but most should understand what I meant.

--
     -Rolf Campbell (39)3-6318

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Sweth Chandramou » Tue, 24 Aug 1999 04:00:00





>>         trying to make a utility out of this sort of task is in
>> many ways ridiculous because the utility would have to have
>> hard-coded into it the algorithm used to do the filename
>> translation.  while an algorithm that matched the shell's
>> (very robust) wildcard syntax _could_ be created, it would
>> probably not be worth the effort; the other option is to do
>> what the dos version does, which is only implement a very
>> small level of wildcard matching.

>    I wouldn't call ?*[] very robust wildcards.  


not operators, all of which together can handle most situations that people
would use them for.  

Quote:>I think full regular-expressions
>would have been a better choice.  But, I don't think they should be changed.  
>It is
>too easy to use somthing like egrep to make the functionality that bash is
>missing:

>alias rls = "ls -l `ls -a1 | grep $1`"

        what regexp would you imagine using this for that can't be duplicated
in straight shell wildcards?

        -- sweth.

--

<a href="http://astaroth.nit.gwu.edu/resume/">Will Work For Food.</a>
<a href="http://astaroth.nit.gwu.edu/~sweth/disc.html">*</a>

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Ken Pizzi » Tue, 24 Aug 1999 04:00:00


On Mon, 23 Aug 1999 15:24:46 -0400,

Quote:>What about "ren *.jpeg *.jpg"? I'm not saying that I agree with what
>Roy Ivy wrote, but I do use command-lines like that frequently, which
>are possible to do in bash, but not easy. The only way I can think of
>doing that is:

>for name in *.jpeg
>do
> mv $name `jpeg2jpg $name`
>done

>And make a program called jpeg2jpg which converted it's command-line parameter.

No need for the external program:
  for name in *.jpeg; do mv "$name" "${name%.jpeg}".jpg; done

Quote:>What I'm really looking for is a regular-expression 'mv' utility that
>would except a command-line like:

>mv "^\(.*\)\.jpeg" "\1.jpg"

Well, not with that syntax, but the "rename" perl script
(packaged in the eg/ subdirectory of perl's source distribution
and also available off the 'net) is quite useful for this:
  rename 's/jpeg$/jpg/' *.jpeg

                --Ken Pizzini

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by Owen M. Astle » Wed, 25 Aug 1999 04:00:00



Quote:> What I'm really looking for is a regular-expression 'mv' utility that
> would except a command-line like:
> mv "^\(.*\)\.jpeg" "\1.jpg"

You can do this in zsh (of course):

alias copy="noglob dos_copy"
alias rename="noglob dos_rename"

(The noglob word means that the following command does not have
globbing, eg * expansion, carried out by the shell).

You could then write functions dos_copy and dos_rename to perform
the copy and rename.

For example:
alpha2-~/tmp% noglob echo *
*
alpha2-~/tmp% echo *
beep.c check.c emacs-20.4-bin-i386.tar.gz sig.c strftime.c temp tensile
tensile.tgz waxs-data xmalloc.c

Owen

 
 
 

Open Letter / Suggestion for shells: Need access to original command line...

Post by super_ban.. » Wed, 25 Aug 1999 04:00:00



[...]

Quote:> No need for the external program:
>   for name in *.jpeg; do mv "$name" "${name%.jpeg}".jpg; done

> >What I'm really looking for is a regular-expression 'mv' utility that
> >would except a command-line like:

> >mv "^\(.*\)\.jpeg" "\1.jpg"

No need to learn shell specifics, try 'mexp' :-)
% mexp "mv *.jpeg *.jpg"

Fetch mexp from:
http://s.pi1.physik.uni-stuttgart.de:80/ophoff/mexp.html
Compile it with:
% gcc -o mexp mexp.c
... put it in /usr/local/bin and you're done.

mexp is also good for things like:
% ls
foo01.jpg foo02.jpg foo03.jpg
% mexp "mv foo??.jpg bar??.jpg"
% ls
bar01.jpg bar02.jpg bar03.jpg

--
Nicolas

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.