How to Keep a Bash Script Running After the Putty Terminal Gets Closed

To keep your script running after the Putty terminal gets closed, you must detach the session in which the script is running. A simple way to detach a session is to use the command screen.

Contents

1. Use the Command screen

1.1 How to Install screen?

On Ubuntu 22.04 server the screen utility is installed by default. If, for some reason, it is not installed, you can install it with:

sudo apt update
sudo apt install screen

(Usually, it is installed even on pretty old servers. I checked on an Ubuntu 14.04 server. And screen was available even there)

Please also see this article.

1.2 How to Use screen?

Suppose you have a very large MySQL dump file /var/www/db_dump.sql. And you need to import it to the database db_name. And the process could take many hours.

Please notice: I put the database dump file in the directory /var/www throughout this article. But you can choose any other directory. Of course, the directory should be safe and not accessible from the Internet.

1. Create the file /var/www/mysql_import.sh

#!/bin/bash

current_script=/var/www/mysql_import.sh
log=/var/www/mysql_import.log
echo "Started: $(date)" > ${log}
mysql -Ddb_name < /var/www/db_dump.sql
echo "Ended: $(date)" >> ${log}
chmod -x ${current_script}

(source)

2. Make the script executable:

cd /var/www
chmod +x mysql_import.sh

If you try to run this script from the Putty terminal window and close the window, import to MySQL will be aborted.

You need to detach the session before closing the Putty window. Use the utility screen for it:

3. Run the utility screen:

screen

It will output a lot of information.

screen command output
Command screen Initial Output

Just press Enter.

4. Run the script:

./mysql_import.sh

5. Press Ctrl A and then D to detach the session.

Also, please see this post on detaching sessions.

6. Close the Putty window. Connect to the server again. Check that the process is still running:

ps -aux | grep mysql_import

The output would be something like this:

root      8531  0.0  0.0   9964  2424 pts/3    S+   16:18   0:00 /bin/bash ./mysql_import.sh
root      8574  0.0  0.0   9204  2296 pts/0    S+   16:23   0:00 grep --color=auto mysql_import

To reattach the detached session:

screen -r

If there are several detached sessions, the output would be like this:

There are several suitable screens on:
        1686.pts-0.u2204    (03/06/2023 02:01:11 AM)    (Detached)
        1672.pts-0.u2204    (03/06/2023 02:00:18 AM)    (Detached)
        1339.pts-0.u2204    (03/06/2023 01:22:32 AM)    (Detached)
Type "screen [-d] -r [pid.]tty.host" to resume one of them.

Also, if you have several detached sessions, you can list them (and their IDs) with:

screen -ls
There are screens on:
        1686.pts-0.u2204    (03/06/2023 02:01:10 AM)    (Detached)
        1672.pts-0.u2204    (03/06/2023 02:00:17 AM)    (Detached)
        1339.pts-0.u2204    (03/06/2023 01:22:31 AM)    (Detached)
3 Sockets in /run/screen/S-root.

Then you can reattach any session as:

screen -r <seession ID>

For example, if the session ID is 1672, then you can reattach it as:

screen -r 1672

To destroy a session, reattach the session, then press Ctrl A, then K, and then Y.

Please also see this post.

Please see this post for screen keyboard shortcuts.

2. Other Solutions

2.1 Run the Process in the Background

You can run the script mysql_import.sh in the background (instead of detaching a session) and close the Putty window:

cd /var/www
chmod +x mysql_import.sh
nohup ./mysql_import.sh &
disown

, where

  • nohup – prevents the process from receiving SIGHUP (Signal Hang UP) signal (source). And sends all the stdout and stderr output to the file nohup.out (by default).
  • & at the end of the line sends the command to the background.
  • disown will disable sending the SIGHUP signal to all active jobs.

Without disown, the MySQL import could be aborted if you closed the Putty window (despite we used nohup).

At least it was aborted for me. The file nohup.out contained:

Terminal close -- query aborted

For some explanation on nohup and background processes please see this post.

Please also see this article and this article.

Please notice: Some sources suggest adding this line to the top of the script (to make the script keep running after the terminal gets closed):

trap "echo 'trap recieved';" SIGHUP SIGINT SIGTERM

It did not work for me. MySQL import was aborted as soon as Putty was closed.

2.2 Set a Cron Job

You can run a command not from Putty directly, but as a cron job. By adding it to a crontab file. But

  • screen is probably a cleaner approach.
  • if you forget to comment the cron job after it’s run, it will run repeatedly. Do you need it?

2.3 Use the Command tmux

You can also use tmux rather than screen to detach a session. Also, see tmux on GitHub. But if you are on some old Linux server (like CentOS 6), tmux might not be available by default.

Sergei Korolev
Sergei Korolev
Web developer and the author of all articles on this site. With over 25 years of programming experience, he has specialized in web programming for more than 19 years. He is a Zend Certified Engineer in PHP 5.3. He is available for hire at a rate of $60 USD per hour. You can see his resume here. Please contact him via this contact form to get a quote. He currently lives in Belgrade, Serbia.

Leave a Reply

Your email address will not be published. Required fields are marked *