reddit / emacs

Run a command over SSH, after activating a virtual env

kornaque · 2022-12-20 13:28
Hi, I would like to run and get the result of a command on a remote host with SSH connection, after having activated a virtual env. In a terminal, I usually do local $ ssh remote remote $ source venv/bin/activate remote (venv) $ midi2wav.py file-on-remote-host.mid How can I do the same in Emacs, with a single command? Ideally, I would like to get the output of the commands as well. After reading the documentation of TRAMP, I decided that `start-file-process` or `shell-command` would be the functions I need. I tried this. (let ((default-directory "/sshx:remote:~/")) (start-file-process "tramp-remote" (get-buffer-create "*Tramp remote process*") "/bin/bash" "-c" "source ~/venv/bin/activate ; midi2wav.py file-on-remote-host.mid")) But nothing appears in the buffer "*Tramp remote process*". There are many other commands for running a program in Emacs, like `call-process`, `process-file`, etc, but I am a bit lost in which can be used here. Thanks for help!
JDRiverRun · 2022-12-20 18:57
A good trick for "activating" a venv temporarily without all the bother is to just call the python executable it stores, so something like: `/venv/bin/python midi2wav.py file-on-remote-host.midi`. So (noting you can't use `~` bare like that): (let ((default-directory (expand-file-name "/ssh:remote:~/my/venv"))) (shell-command-to-string "bin/python3 -V"))
astoff1 · 2022-12-21 07:48
To complement this a bit, the permanent way to do it is to set the variable `tramp-remote-path`. You can use a connection-local variable if you use multiple Tramp remotes.
kornaque · 2022-12-22 11:18
Awesome! Thank you! I did not know that all `source venv/bin/activate` was doing was just setting the `PATH` variable. So directly getting to the `bin/` folder does the trick. EDIT: I solved my second question concerning setting the shell, thanks to connection-locale variables, thanks guys! :) Second question: Is there any way to choose in which shell the command will be executed? Solution: Use connection-local variable to set the shell to /bin/fish, for example. ``` (connection-local-set-profile-variables 'remote-fish '((shell-file-name . "/bin/fish") (shell-command-switch . "-c") (shell-interactive-switch . "-i") (shell-login-switch . "-l"))) (connection-local-set-profiles '(:application tramp :protocol "ssh" :machine "myremote") 'remote-fish) (let ((default-directory (expand-file-name "/ssh:myremote:~/"))) (with-connection-local-variables (shell-command-to-string "foobar") )) ``` Now, if fish is installed on the remote, it should run as the shell!