0

I have written a Python code to generate a shell script and then run the script using subprocess.

The script file is created, but when I try to run from within the code, it is not doing anything. If I try to run the same script with a file that I have created outside the script, it is working as expected.

Here is my code :

import subprocess
import os

cwd = os.getcwd()
file_name = cwd + "/cmd_file_from_python"
fd = open(file_name,"w")
fd.write("#!/usr/local/bin/tcsh -f\n")
fd.write("echo 'PRINT FROM CMD_FILE_FROM_PYTHON'\n")
fd.close

os.chmod(file_name, 0o777)

cmd=file_name
p = subprocess.Popen(cmd,executable='/bin/ksh', shell=True, stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
(stdout,stderr) = p.communicate()
p_status = p.wait()
print "Command output : ", stdout
print "Command outerr : ", stderr
print "Command exit status/return code : ", p_status
print "================================================================"

file_name = cwd + "/cmd_file"
cmd = file_name
p = subprocess.Popen(cmd,executable='/bin/ksh', shell=True, stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
(stdout,stderr) = p.communicate()
p_status = p.wait()
print "Command output : ", stdout
print "Command outerr : ", stderr
print "Command exit status/return code : ", p_status

and the output :

Command output :
Command outerr :
Command exit status/return code :  0
================================================================
Command output :  PRINT FROM CMD_FILE

Command outerr :
Command exit status/return code :  0

Here is the code of the script which I created outside the code:

$ cat cmd_file
#!/usr/local/bin/tcsh -f
echo 'PRINT FROM CMD_FILE'

IF I check both files, they only difference is the print :

$ diff cmd_file_from_python cmd_file
2c2
< echo 'PRINT FROM CMD_FILE_FROM_PYTHON'
---
> echo 'PRINT FROM CMD_FILE'
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
Boazsh
  • 11
  • 3
  • 1
    Side-note: Why are you explicitly specifying `executable='/bin/ksh'` when you're running scripts with shebang lines that specify `tcsh`. It seems kind of pointless, when the default executable would launch the `tcsh` script just fine. It also doesn't seem like there is any reason to use `shell=True` here, since you're not passing a string with arguments, nor doing any shell related things in the command. `shell=True` is opening security/stability holes for no reason. – ShadowRanger Jan 17 '19 at 01:54
  • I regret that I have but one vote to give to ShadowRanger's comment. Sigh. The only thought I have for why one would do that would be because one is doing this as a spike test in preparation for making a bigger mistake. Just invoke the script you made directly, rather than calling on a proxy to run it for you. – Ed Grimm Jan 17 '19 at 02:42

1 Answers1

1

Your file is empty while the program is running:

fd = open(file_name,"w")
fd.write("#!/usr/local/bin/tcsh -f\n")
fd.write("echo 'PRINT FROM CMD_FILE_FROM_PYTHON'\n")
fd.close

Note the lack of call parens on fd.close; you never actually closed the file, so the entire contents of the file were likely sitting in Python's buffer, and never go to disk until the program ends (when the CPython reference interpreter, as an implementation detail, goes through and cleans up globals, closing the open files for you by side-effect; it might never reach disk in another interpreter).

To fix, actually call close. Or even better, switch to the much safer with statement approach, where the close is implicit, and automatic, occurring even if an exception or return causes you to exit the code early:

with open(file_name, "w") as fd:
    fd.write("#!/usr/local/bin/tcsh -f\n")
    fd.write("echo 'PRINT FROM CMD_FILE_FROM_PYTHON'\n")
# No need to call close; file is guaranteed closed when you exit with block
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • I am confused... Why does your proposed answer not include fixing the shell nonsense that you mentioned in your comment? – Ed Grimm Jan 17 '19 at 02:59
  • @EdGrimm: Because the shell nonsense isn't the cause of the OP's problem, at all. It's pointless and [bad code](https://stackoverflow.com/a/13491911/364696), but not related to the problem; there are more than enough sources for why it's a problem and how to fix it. – ShadowRanger Jan 17 '19 at 03:01