I’m attempting to construct and execute a csh script from python.
The code I have produces what looks like a correct script, and os.system("my_script.csh") returns ‘0’, but the script doesn’t perform the task within it unless I go into it manually using vim and re-save it (changing nothing in the script manually – i don’t even enter ‘insert’ mode). What is it that re-saving in vim does that isn’t being done in my code, and is it possible to do it?
Here’s the relevant part of my code:
grabmeName = '%sgrabme%s.csh'%(dirNames['grabmes'],uniqID)
if not os.path.exists(grabmeName):
open(grabmeName,'w').close()
os.chmod(grabmeName,0777)
with open(grabmeName,'a') as f:
f.write("#!/bin/csh -f\n")
f.write("echo 'hello'")
os.system(grabmeName)
The main problem is that every line in the shell needs to end with a
\nin order to be executed, even the last line. You can just add\nto the end of the"echo 'hello'"string. This is arguably a bug incsh, sincebashand friends don’t have this problem, but if you want to usecsh, you’ll have to accommodate it.When you save a text file in vim, it adds a trailing newline to the file if there wasn’t one to begin with. You can verify this by saving a copy of the file beforehand and running
diffto see what vim changes:You can turn off this behaviour of vim in your
~/.vimrcif you’d like. See:help 'eol'in vim help.Another potential problem is that
system(filename)will only work iffilenameis a non-bare path—i.e., has a/in it—or if.is in the system$PATH.Additionally, by using
os.open()instead ofopen(), you can set the file permissions at file creation time. Here it might not make a big difference, but in many contexts, creating the file and then changing its permissions results in a security vulnerability. This stackoverflow question shows how to do that.Putting it all together, you’d get something like this: