Access to raw command line?

P

Pieter Edelman

Hi,

I'm currently writing a command-line program in Python, which takes
commands in the form of:
../myprog.py [OPTIONS] ARGS
So pretty standard stuff. In my case, ARGS is a list of image files.

One of the possible options is to specify a file holding information
about the photos. You'd specify it with (in this particular case) the -
t switch, and you can specify multiple files by repeating this switch:
../myprog.py -t info1.gpx -t info2.gpx -t info3.gpx *jpg

Now, one of the users has quite a lot of info files, and asked me if
it's possible to use a wildcard in specifying these, so he would just
have to do:
../myprog.py -t *.gpx *.jpg

This seems like a sensible option at first sight, but it's difficult
to implement because the wildcard is expanded by the shell, so
sys.argv gets a list containing "-t", all .gpx files and all .jpg
files. With this list, there's no way to tell which files belong to
the "-t" switch and which are arguments (other than using the
extension).

One possible way to work around this is to get the raw command line
and do the shell expansions ourselves from within Python. Ignoring the
question of whether it is worth the trouble, does anybody know if it
is possible to obtain the raw (unexpanded) command line?
Alternatively, does anybody have suggestion of how to do this in a
clean way?

Thanks,
Pieter
 
L

Laurent Pointal

Pieter Edelman a écrit :
One possible way to work around this is to get the raw command line
and do the shell expansions ourselves from within Python. Ignoring the
question of whether it is worth the trouble, does anybody know if it
is possible to obtain the raw (unexpanded) command line?
Alternatively, does anybody have suggestion of how to do this in a
clean way?

To avoid shell extension, try to quote args:
../myprog.py -t "*.gpx" "*.jpg"


Or (IMHO simpler) define anoter switch to identify other files:
../myprog.py -t *.gpx -u *.jpg

A+

Laurent.
 
G

Gabriel Genellina

Now, one of the users has quite a lot of info files, and asked me if
it's possible to use a wildcard in specifying these, so he would just
have to do:
./myprog.py -t *.gpx *.jpg

This seems like a sensible option at first sight, but it's difficult
to implement because the wildcard is expanded by the shell, so
sys.argv gets a list containing "-t", all .gpx files and all .jpg
files. With this list, there's no way to tell which files belong to
the "-t" switch and which are arguments (other than using the
extension).

I can't verify right now, but I think that using -t "*.gpx" would avoid
the shell expansion. (Or perhaps '*.gpx' or \*.gpx or even -t*.gpx)
 
B

Bjoern Schliessmann

Pieter said:
./myprog.py -t *.gpx *.jpg

This seems like a sensible option at first sight, but it's
difficult to implement because the wildcard is expanded by the
shell,

(in *nix only)
so sys.argv gets a list containing "-t", all .gpx files and
all .jpg files. With this list, there's no way to tell which files
belong to the "-t" switch and which are arguments (other than
using the extension).

One possible way to work around this is to get the raw command
line and do the shell expansions ourselves from within Python.
Ignoring the question of whether it is worth the trouble, does
anybody know if it is possible to obtain the raw (unexpanded)
command line?

Breaking the "de-facto standards" isn't a good idea, IMHO.
Alternatively, does anybody have suggestion of how to do this in
a clean way?

First, you could define another wildcard character, or let users
escape the * like this: ./myprog.py -t \*.gpx \*.jpg

Let users give a list of files to process, and default to looking
for the same filename without image extension and with ".gpx".
E. g.:

../myprog.py -t .gpx *.jpg

will expand to:

../myprog.py -t .gpx a.jpg b.jpg [...] z.jpg

What your program's "policy" would be depends on its exact function.
I'm thinking about if the program silently fails if it doesn't find
a .gpx file for one .jpg, for example, or if it complains about it.

Regards,


Björn
 
M

Michael Hoffman

Pieter said:
Hi,

I'm currently writing a command-line program in Python, which takes
commands in the form of:
./myprog.py [OPTIONS] ARGS
So pretty standard stuff. In my case, ARGS is a list of image files.

One of the possible options is to specify a file holding information
about the photos. You'd specify it with (in this particular case) the -
t switch, and you can specify multiple files by repeating this switch:
./myprog.py -t info1.gpx -t info2.gpx -t info3.gpx *jpg

Now, one of the users has quite a lot of info files, and asked me if
it's possible to use a wildcard in specifying these, so he would just
have to do:
./myprog.py -t *.gpx *.jpg

This seems like a sensible option at first sight, but it's difficult
to implement because the wildcard is expanded by the shell, so
sys.argv gets a list containing "-t", all .gpx files and all .jpg
files. With this list, there's no way to tell which files belong to
the "-t" switch and which are arguments (other than using the
extension).

One possible way to work around this is to get the raw command line
and do the shell expansions ourselves from within Python. Ignoring the
question of whether it is worth the trouble, does anybody know if it
is possible to obtain the raw (unexpanded) command line?
Alternatively, does anybody have suggestion of how to do this in a
clean way?

One option would be to accept a directory argument to -t and to
recursively inlcude all the gpx files in that directory.

Another option would be to use some sort of optional separator, like

../myprog.py -t *.gpx -j *.jpg

where everything between -t and -j would be considered a -t option. I
think this breaks the usual UNIX options paradigm though. Of course UNIX
itself does that--dd is an example of a program that doesn't follow it.

Another option would be to accept a list of gpx files from a file:

find . -name '*.gpx' > gpxlist.txt
../myprog.py --gpx-file=gpxlist.txt *.jpg

Or to accept more than one file per argument:

../myprog.py -t "$(echo *.gpx)" *.jpg

Personally I would prefer the file list approach. If you start expanding
wildcards yourself, then if someone stupidly wants to use a wildcard
character, they'll have to triple-escape things, and it'll just be messy.
 
G

Grant Edwards

Hi,

I'm currently writing a command-line program in Python, which takes
commands in the form of:
./myprog.py [OPTIONS] ARGS
So pretty standard stuff. In my case, ARGS is a list of image files.

One of the possible options is to specify a file holding information
about the photos. You'd specify it with (in this particular case) the -
t switch, and you can specify multiple files by repeating this switch:
./myprog.py -t info1.gpx -t info2.gpx -t info3.gpx *jpg

Now, one of the users has quite a lot of info files, and asked me if
it's possible to use a wildcard in specifying these, so he would just
have to do:
./myprog.py -t *.gpx *.jpg

This seems like a sensible option at first sight, but it's difficult
to implement because the wildcard is expanded by the shell,

You should buy a new keyboard. The latest ones have quote
keys -- both single _and_ double!
 
M

Michele Simionato

Hi,

I'm currently writing a command-line program in Python, which takes
commands in the form of:
./myprog.py [OPTIONS] ARGS

Once you start having too many arguments and options on the command
line, you might
consider using the cmd module of the standard library instead. Then
you could implement your own
expansion, and you would have portability for non-Unix system too.

Michele Simionato
 
P

Pieter Edelman

All your posts pretty much confirmed my own thoughts on this subject.
Every option requires a specific action from the user, and as Bjoern
points out, it would differ from what everybody is used to. I think
there's no trivial and reliable way to do this, so I can better leave
it the way it is (at least for now).

Everybody thanks for your insights,
Pieter
 
G

Grant Edwards

All your posts pretty much confirmed my own thoughts on this subject.
Every option requires a specific action from the user, and as Bjoern
points out, it would differ from what everybody is used to. I think
there's no trivial and reliable way to do this, so I can better leave
it the way it is (at least for now).

Quoting things on the command line that you don't want the
shell to expand is trivial and reliable. It's also something
than any shell user should know.
 
D

Donn Cave

Pieter Edelman said:
One possible way to work around this is to get the raw command line
and do the shell expansions ourselves from within Python. Ignoring the
question of whether it is worth the trouble, does anybody know if it
is possible to obtain the raw (unexpanded) command line?

If you're on VMS (well, you didn't say), you're in luck.

The UNIX shell has already expanded the file globbing by the
time your program starts up, but VMS leaves it to the application,
with the help of a handy RMS$ function or two so it gets done in
a consistent way. This allows the command line interface to
interact with the user in a little more transparent way, since
the input seen by the program is congruent with what the user
typed in. E.g., "rename *.jpeg *.jpg" is trivial on VMS,
impossible on UNIX.

Donn Cave, (e-mail address removed)
 
G

Grant Edwards

If you're on VMS (well, you didn't say), you're in luck.

The UNIX shell has already expanded the file globbing by the
time your program starts up, but VMS leaves it to the application,
with the help of a handy RMS$ function or two so it gets done in
a consistent way. This allows the command line interface to
interact with the user in a little more transparent way, since
the input seen by the program is congruent with what the user
typed in. E.g., "rename *.jpeg *.jpg" is trivial on VMS,
impossible on UNIX.

Typing rename '*.jpeg' '*.jpg' is impossible?
 
P

Pieter Edelman

Yes, but I want to make it less difficult for my end users, not more
difficult. I think the best is to require an extra switch for the
photo files, as some of the people here suggested.
 
P

Pieter Edelman

Of course you're right about that. I think an optional GUI or wizard-
like interface (in this particular case) would be best, but I was
looking for an easy fix :) Thanks for the suggestion though.

I'm currently writing a command-line program in Python, which takes
commands in the form of:
./myprog.py [OPTIONS] ARGS

Once you start having too many arguments and options on the command
line, you might
consider using the cmd module of the standard library instead. Then
you could implement your own
expansion, and you would have portability for non-Unix system too.

Michele Simionato
 
D

Donn Cave

Grant Edwards said:
Typing rename '*.jpeg' '*.jpg' is impossible?

It is not (of course, nor is implementation impossible), but as
noted earlier in this thread it isn't idiomatic. You can present
an interface like this to a user who has been specially trained
to use it, but no one would naturally expect it to work, without
prior instruction, so it isn't any more or less interesting than,
say, "rename *.jpeg .jpeg". (Oops, now that I think of it, that's
what I should have said works on VMS anyway. Been too long.)

Donn Cave, (e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top