?sys.argv values more literally?

Donn Cave donn at u.washington.edu
Fri Apr 28 13:56:39 EDT 2000


Quoth Norman Shelley <Norman_Shelley-RRDN60 at email.sps.mot.com>:
| I need to write a frontend program that will call one of two other
| programs (both of which are NOT binaries but are tcl programs therefore
| they HAVE to be invoke with os.system() or "/bin/sh" has to be the first
| argument to a os.execv() call).
|
| THe frontend program must detect a "-ver someversionname" options and
| remove the two words and then call the appropriate tcl program with the
| EXACT arguments given on the command line (less those two words).
| Problem is words in sys.argv
| that were quoted on the command line look like words that were not
| quoted on the command, e.g.
|
| %frontend -ver 1.0 word1 word2 "word three" "word(three)"
| argv looks like
| ["frontend", "-ver", "1.0", "word1", "word2",  "word three",
| "word(three)"]
|
| but this fails when os.system or os.execv is called (with frontend,
| -ver, and 1.0 replaced with the tcl program full pathname (/bin/sh added
| at front  for execv) as "word three" and "word(three)" are missing there
| protective quotes (the /bin/sh needs to see those as one word not two
| words or a word  with parens).
|
| I need   argv to look like this:
| ["frontend", "-ver", "1.0", "word1", "word2",  '"word three"',
| '"word(three)"']
| where words that were quoted on the command line are strings with
| beginning and ending quotes in the argv.
|
| Any way to do this or get around this problem?

As another followup has noted, it's OK to quote all of them.  The
python interpreter never gets the quotes you want, they're for the
benefit of the shell that invokes python.

However, I think it solves the problem the wrong way, and I'm not
convinced the problem is real either.  What happens if an original
argument includes a quoted quote?  This extra run through the shell
interpreter is not healthful.

When we call system() to execute a command, as you surmised we're
executing /bin/sh, specifically in effect it's like this:
  execv('/bin/sh', ('sh', '-c', command_line))

This shell parses the command line, locates its argv0 file and
in turn execs it.  We don't need to know how that file is implemented,
because the shell can run any command.  Not because it has any magic
powers, but because UNIX can run any well-formed executable file
including scripts.  Python can do the same as the shell, and if you
can figure out how to get that working, you can exec your command
directly and omit the re-quoting.

I can't say why Tcl scripts might need to be executed by /bin/sh,
so I can't be much help there.  If they were really shell scripts,
I'd say they might need an appropriate #! line, the line at the
top of the script file that specifies its interpreter.  E.e.g.,
#!/bin/sh                 or
#!/usr/bin/env python     or
#!/bin/awk -f             etc.

In the absence of this line, the UNIX exec fails and the shell will
usually try to execute the script itself.  If you want to have a
rule like that when you invoke programs, you can make the default
whatever you want for your implementation - the shell, Tcl, etc. -
but it's much better to fix the file so the UNIX exec will work as
intended.

	Donn Cave, University Computing Services, University of Washington
	donn at u.washington.edu

PS.  The HTML and V-card didn't help much.



More information about the Python-list mailing list