I'm about to run an python script on Ubuntu on VPS. It's is machine learning training process so take huge time to train. How can I close putty without stopping that process.
-
1Check out `nohup`. – phk Apr 29 '17 at 13:10
3 Answers
You have two main choices:
Run the command with
nohup. This will disassociate it from your session and let it continue running after you disconnect:nohup pythonScript.pyNote that the stdout of the command will be appended to a file called
nohup.outunless you redirect it (nohup pythonScript.py > outfile).Use a screen multiplexer like
tmux. This will let you disconnect from the remote machine but then, next time you connect, if you runtmux attachagain, you will find yourself in exactly the same session. The command will still be running (it will continue running when you log out) and you will be able to see its stdout and stderr just as though you'd never logged out:tmux pythonScript.pyOnce you've launched that, just close the PuTTY window. Then, connect again the next day, run
tmux attachagain and you're back where you started.
- 1,505
- 1
- 11
- 18
- 234,489
- 66
- 447
- 667
-
5
-
-
1`nohup python -u your_code.py &` and printout, log will be saved in "nohup.out " file – chickensoup Aug 26 '20 at 06:26
-
I don't think python scripts run that way without specifying `python` or `python3` – Pe Dro Mar 20 '21 at 18:51
-
@PeDro of course they do. As long as they are properly written and have a [shebang line](https://en.wikipedia.org/wiki/Shebang_(Unix)) they will run just like any other script. You could simply try it and see. – terdon Mar 20 '21 at 18:52
The screen tool, available for all Linux distros, supports this.
To install it, run apt-get install screen for deb-based Linux distros, or
dnf install -y screen or yum install -y screen for RPM-based ones.
To use:
$ screen
A new shell is started. In this shell, you can start your Python script. Then you can press Ctrl+Shift+A then D. It will detach your terminal from the shell that is running your script. Furthermore, the script is still running in it.
To see how your script is running, you can call screen -r.
This will reattach your terminal to the shell with the Python script you left running in background.
UPD: as Fox mentioned, screen works badly with systemd, but we can use systemd to start the script, like they say in official example.
For example, if your script is started by /usr/bin/myPythonScript, you can create Systemd unit file, like this.
$ cat /etc/systemd/system/myPythonScript.service
[Unit]
Description=MyPythonScript
[Service]
ExecStart=/usr/bin/myPythonScript
[Install]
WantedBy=multi-user.target
Than, you can start this script
# systemctl daemon-reload
# systemctl start myPythonScript
If you want to make this script started automatically on system start -
# systemctl enable myPythonScript
Anytime you can view how your script is running
# systemctl status myPythonScript
Ad you can review logs of your script
# journalctl -u myPythonScript -e
- 121
- 3
-
Note that `screen` does not exactly play nicely with `systemd` in its default configuration. I don't know if Ubuntu uses `systemd`, but [the behavior and workaround](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=825394) might be worth mentioning in your answer – Fox Apr 30 '17 at 06:47
Most processes can be fooled by redirecting its stdout, stderr, stdin (not all descriptors are always necessary to redirect) and using & control operator.
See that ping example.com 1>/dev/null & does the job.
Of course, some programs are more sophisticated and require such solutions as @terdon mentioned, but it's good to know and use what fits best.
EDIT: as written in this answer kills systemd processes on logout. Some versions of systemd kill processes on logout by default, others don't. This behavior can be changed by modifying /etc/systemd/logind.conf by setting the following option. As written, it may also solve some issues you may have with @terdon's solutions.
from man logind.conf:
KillUserProcesses=Takes a boolean argument. Configures whether the processes of a user should be killed when the user logs out. If true, the scope unit corresponding to the session and all processes inside that scope will be terminated. If false, the scope is "abandoned", see systemd.scope(5), and processes are not killed. Defaults to "yes", but see the options
KillOnlyUsers=andKillExcludeUsers=below.In addition to session processes, user process may run under the user manager unit [email protected]. Depending on the linger settings, this may allow users to run processes independent of their login sessions. See the description of
enable-lingerinloginctl(1).Note that setting
KillUserProcesses=yeswill break tools likescreen(1) andtmux(1), unless they are moved out of the session scope. See example insystemd-run(1).
Read linked answer to find out more.
- 512
- 6
- 13
-
1This simply sends the process to the background. The OP wants to be able to disconnect from a remote ssh session and have the process continue. This won't help in that situation, exiting the remote session will stop the command even if it is in the background. – terdon Apr 29 '17 at 19:35
-
@terdon have you checked if my example works? I have checked and it works for *some* commands, as I have written in my answer. – styrofoam fly Apr 29 '17 at 19:37
-
Yes, I have checked and yes, I have seen that sometimes the command continues. I have, however, very often seen that the command stops so unless you can explain exactly what commands continue or provide a way of knowing in advance whether it will continue or not, this isn't very useful. In fact, the specific example you gave failed on a test I just ran connecting from my Arch to a remote Ubuntu system. – terdon Apr 29 '17 at 19:42
-
@terdon funny, I have checked this on local ArchLinux connecting to remote PLD. The only rule that works all the time is "does the program use `isatty()` and exits if it isn't?" – styrofoam fly Apr 29 '17 at 19:52
-
That might merit its own question. I know I used to always need nohup, and then at some point something changed and I sometimes didn't. I can't see how the isatty could be it though, if you exit the parent shell, that should also kill the child. But yes, sometimes it doesn't. I am guessing it must be configurable somehow. – terdon Apr 29 '17 at 22:45
-
On logging out (or rather, losing the terminal), the program gets the [SIGHUP](https://en.wikipedia.org/wiki/SIGHUP) signal, which, by default, terminates. Nothing in your answer solves that. And before you ask _"have you checked if my example works?"_, yes I have and it doesn't work for me. – marcelm Apr 30 '17 at 09:56