Open shaunvxc opened 8 years ago
It sounds like you might want to use exec
https://en.wikipedia.org/wiki/Exec_(system_call)
https://docs.python.org/2/library/os.html#os.execl
something like
import os
os.execl("/usr/local/bin/vim", "--", "/tmp/editme")
This seems to work. However, many have mentioned to be that it is bad practice to use os.system()
-- I'm wondering if the same sort of thing applies to os.execl()
?
Using this approach would require users to specify the full path to the executable when exporting $EDITOR
(EDITOR=/usr/local/bin/vim
vs. EDITOR=vim
). Not sure whether or not that is something I should worry about.
Thank you very much though-- I will certainly consider this to fix my issue.
Couple things to note:
os.execl
wrong. First argument is the binary, which you have correct, the rest is argv. argv[0] should be the program you're trying to execute, so you really should have written something like this:args = ["/usr/local/bin/vim", "--", "/tmp/editme"]
os.execl(args[0], *args)
But there's technically no need for argv[0]
and the binary to match. Most programs just happen not to care about what's in argv[0]
. argv[0]
is what shows up in the process tree, so in your case above, you'd see vim labelled as "--".
$ pgrep -a vim
3002 --
os.execlp
(This applies to all the "p" variants), does $PATH
lookup. You probably want that if you want to go down that road.os.execl
isn't equivalent to os.system
or subprocess32
. It directly replaces the current process with a new process. So in this case, vim replaces python and you will not return to your python program. You'll have to fork (os.fork
) first. You can consider this a very trivial optimization if your program effectively ends with the launching of vim (Sorry if I'm explaining things you already know, better err on the side of too verbose).Now if you look at subprocess's source (https://github.com/python/cpython/blob/2.7/Lib/subprocess.py) you can see how it does things. It basically wraps forking, exec (it uses os.execvp
in particular), and waiting (os.waitpid
) - while also wrapping up error handling, so forth. So there should be no reason why using the lowlevel stuff directly vs subprocess should make a difference.
Continuing on from my previous comments (I'm OCCASIONAL_CATNAPPER on reddit), I'd suspect maybe you have two copies of vim, on in /usr/bin/local and one elsewhere and maybe that's the difference for why os.execl worked.
Thanks so much for taking the time to write up such a helpful response! os.execlp()
does the trick, I will update the code to use this instead of subprocess
.
As far as why subprocess
doesn't work for me-- I still can't tell. I'll play around with it a bit more.
I'm fairly certain I only have one vim installation-- the only one I can find lives in /usr/bin
. One thing to clarify-- launching vim from subprocess was never the issue-- it would just be launched in a frozen state (apologies if you were already aware of this).
Anyways, thanks again!
One last thing actually, try attach strace to the stuck vim process and see what its hanging on. It'll tell you which syscall its stuck on, which can be useful in figuring out exactly whats broken.
vim
does not want to play nicely when launched from anenvy edit
call using python'ssubprocess
module. Currently, if$EDITOR
is set to bevim
, it will launch, but in a frozen state.Not quite sure if there is a workaround for this yet (I see others having similar issues on stackoverflow).
vi
works just fine, so in the meantime (see 06c4392408222ed611073e31e02ee872ccda5f38, and as of 0.0.8),envy edit
will default tovi
if :$EDITOR
is not set.$EDITOR
is set to bevim
While it does feel a little strange to both rely on
$EDITOR
but ignore it in a specific case (ievim
), the logic is thatenvy edit
is not useful AT ALL if$EDITOR
is set tovim
. (vi
should be available on most systems..)Any suggestions as to how to better work around (or solve!) this issue would be greatly appreciated!