This is a job very well suited for systemd.
Running a script as a systemd service
If your system is running systemd, then you can configure your script to run as a systemd service which provides control over the lifecycle and execution environment, as well as preconditions for starting the script, such as the network being up and running.
Create your systemd unit file under /lib/systemd/system, e.g. with vim /lib/systemd/system/autossh.service:
[Unit]
# By default 'simple' is used, see also https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=
# Type=simple|forking|oneshot|dbus|notify|idle
Description=Autossh keepalive daemon
## make sure we only start the service after network is up
Wants=network-online.target
After=network.target
[Service]
## here we can set custom environment variables
Environment=AUTOSSH_GATETIME=0
Environment=AUTOSSH_PORT=0
ExecStart=/usr/local/bin/ssh-keep-alive.sh
ExecStop=pkill -9 autossh
# don't use 'nobody' if your script needs to access user files
# (if User is not set the service will run as root)
#User=nobody
# Useful during debugging; remove it once the service is working
StandardOutput=console
[Install]
WantedBy=multi-user.target
Now you can test the service:
systemctl start autossh
Checking the status of the service:
systemctl status autossh
Stopping the service:
systemctl stop autossh
Once you verified that the service works as expected enable it with:
systemctl enable autossh
NOTE: For security purposes systemd will run the script in a restricted environment, similar to how crontab scripts are run, therefore don't make any assumptions about pre-existing system variables such as $PATH. Use the Environment keys if your script needs specific variables to be defined. Adding set -x at the top of your bash script and then running systemctl status my_service might help identify why your script is failing. As a rule of tumb, always use absolute paths for everything including echo, or explicitly define your $PATH.