48a49,69> .. warning::> > Do not put the entire command into one string as your *args* when> *shell=False*, unless you're not giving the command any arguments at all::> >>>> p1 = Popen(args="/home/arthur/print_args.py -input eggs.txt")> Traceback (most recent call last):> ...> OSError: [Errno 2] No such file or directory>>>> p2 = Popen(args=["/home/arthur/print_args.py -input eggs.txt"])> Traceback (most recent call last):> ...> OSError: [Errno 2] No such file or directory> > Shell equivalent to these erroneous examples (note the quotes)::> $ '/home/arthur/print_args.py -input eggs.txt'> -sh: /home/arthur/print_args.py -input eggs.txt: No such file or directory> > Notice in these cases that the system is trying to execute a (nonexistent)> program whose name includes the entire command string, arguments and all.> 53a75,88> .. note::> > Determining the exact correct *args* value for a given shell command string> can be tricky, especially in complex cases. > :meth:`shlex.split` can be very helpful when trying to determine the correct> tokenization::> >>>> import shlex, subprocess>>>> command_line = raw_input("Command line:")> /bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "python -c 'print __name__'">>>> shlex.split(command_line)> ['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "python -c 'print __name__'"]>>>> p = subprocess.Popen(['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "python -c 'print __name__'"]) #Success!> 58a94,107> .. warning::> > When constructing a command string and using *shell=True*, be mindful of> escaping characters of special meaning to the shell::> >>>> filename = "has some spaces">>>> subprocess.Popen("rm "+filename, shell=True) #WRONG: deletes 3 files named "has", "some", and "spaces">>>> subprocess.Popen("rm "+filename.replace(' ', r'\ '), shell=True) #CORRECT: deletes one file>>>> subprocess.Popen("rm "+('"%s"' % filename), shell=True) #ALSO CORRECT>>>> subprocess.Popen(["rm", filename], shell=False) #SAFER: Now you don't need to worry about the escaping> > This and similar pitfalls are why one should avoid using *shell=True*> whenever feasible.> 242a292,341> An Illustrative Example> ^^^^^^^^^^^^^^^^^^^^^^^> Determining the correct *args* for a given shell command string can be tricky.> Here, a worked example is presented to help get a feel for shell tokenization> and calling :class:`Popen`'s constructor.> > The following simple program can be used to empirically inspect the arguments> passed to it::> > #!/usr/bin/env python> #print_args.py: Prints each of its command line arguments on a separate line, with index numbers> import sys> for index, arg in enumerate(sys.argv):> print ("%s:" % index), arg> > Here is a particularly complex shell command line invoking the program::> > $ ./print_args.py -input eggs.txt -output "spam spam.txt" -cmd "python -c 'print __name__'"> 0: ./print_args.py> 1: -input> 2: eggs.txt> 3: -output> 4: spam spam.txt> 5: -cmd> 6: python -c 'print __name__'> > .. warning::> > "-input" and "eggs.txt" are two separate arguments to the program, even> though one is the parameter of the other. For example, this would be wrong> (note the differing output)::> >>>> p = subprocess.Popen(["./print_args.py", "-input eggs.txt"])> 0: ./print_args.py> 1: -input eggs.txt> > Here is the shell equivalent to illustrate the problem::> > $ ./print_args.py '-input eggs.txt'> > The same applies to the other argument pairs.> > Here are equivalent ways to invoke the program with the same arguments as before::> >>>> p1 = subprocess.Popen('./print_args.py -input eggs.txt -output "spam spam.txt" -cmd "python -c \'print __name__\'"', shell=True)>>>> p2 = subprocess.Popen('./print_args.py -input eggs.txt -output spam\\ spam.txt -cmd "python -c \'print __name__\'"', shell=True)>>>> p3 = subprocess.Popen(["./print_args.py", "-input", "eggs.txt", "-output", "spam spam.txt", "-cmd", "python -c 'print __name__'"], shell=False) #MOST PREFERRED> > The last method, with *shell=False*, is the most recommended one.> 548d646 <

AltStyle によって変換されたページ (->オリジナル) /