0

We have python version - 2.7.5 on my Linux machine - redhat 7.3

I write this simple script in order to use sed to replace string in file

more test.py #!/usr/bin/env python import subprocess subprocess.call("sed s'/2.6/2.6.4/g' /tmp/file.xml") 

but we got

Traceback (most recent call last): File "./test.py", line 5, in <module> subprocess.call("sed s'/2.6/2.6.4/g' /tmp/file.xml") File "/usr/lib64/python2.7/subprocess.py", line 524, in call return Popen(*popenargs, **kwargs).wait() File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__ errread, errwrite) File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory 

what is wrong with the python script ?

 more file.xml 2.6.0.3-8 
3

1 Answer 1

1

In Python:

when using

args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names). If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.
...
If shell is True, the specified command will be executed through the shell. This can be useful if you are using Python primarily for the enhanced control flow it offers over most system shells and still want convenient access to other shell features such as shell pipes, filename wildcards, environment variable expansion, and expansion of ~ to a user’s home directory.

So, your approach will work when specifying:

subprocess.call("sed s'/2\.6/2.6.4/g' /tmp/file.xml", shell=True) 

But ...

Warning: Using shell=True can be a security hazard.
Executing shell commands that incorporate unsanitized input from an untrusted source makes a program vulnerable to shell injection, a serious security flaw which can result in arbitrary command execution. For this reason, the use of shell=True is strongly discouraged in cases where the command string is constructed from external input.

When using shell=True, pipes.quote() can be used to properly escape whitespace and shell metacharacters in strings that are going to be used to construct shell commands.

Conclusion: when passing args (i.e. command) as a single string (with shell=True being set) you should at least escape/quote it. But, as mentioned above, providing a sequence of arguments is highly preferred:

import subprocess subprocess.call(['sed', 's/2\.6/2.6.4/g', '/tmp/file.xml']) 

    You must log in to answer this question.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.