tmux detach while running script - terminal

So I have a script that I would like to run on my server and not have it bother me. So I thought I would run the server in a tmux window and then detach it so I could simply attach if I ever want to look at the progress (this script will take days to run).
but when I run my script in the tmux window, I am not able to detatch while it is running. Is there something I am doing wrong? How can I detach while this still runs? I feel like I am being very oblivious to an obvious solution here.

You can detach from a tmux session while leaving the script running by:
CTRL + b, then pressing d
You can enter back into the session by running tmux attach -t <session id>

Related

How to enter keyboard shortcuts in bash script

Is it possible to enter keyboard shortcuts into a bash script? For example, I have tried typing in ^d to substitute for control + d (logout) without success.
ubuntu#vfleet:~$ ^d
-bash: :s^d: substitution failed
ubuntu#vfleet:~$ ^D
-bash: :s^D: substitution failed
I am using screen to run a django development server in the background. One of the commands to run a particular screen as a daemon is control + a + d. The goal is to be able to enter in control + a + d into a bash script. For example:
python manage.py runserver
^a + d
Is this possible?
Edit:
A valid method of avoiding the keyboard shortcut in screen is linked by Eric Renouf in the comments below. screen -d -m sh -c "python manage.py runserver" will start a development server as a daemon. This is a great solution for my particular problem, but it would still be nice to have a solution for the original question at hand.
xdotool package is the solution here.
xdotool key ctrl+d
Full reference
You probably should just start the command without attaching to the screen session in the first place, like
screen -d -m python manage.py runserver
but if you can't do that for some reason, you could detach from a screen session you're currently in by doing:
screen -S "$STY" -X detach
screen saves its current session info in STY, so we'll use that to make sure we're interacting with the correct session (in case there are many). Then we'll use -X to send a command to that session, in this case our command will be detach which will detach all the attached sessions, including the one used to execute that command
So while this doesn't actually send key strokes, it does highlight that there is often another command that you can send to accomplish your goals. Here detach takes the place of ctrl+a+d. Sending quit or running exit could often replace ctrl+d.
Another work-around would be to use expect which you could then use to send the strings containing control characters or hex values of them.

unix - running a shell script in the background and creating an output log

What's the best way to run this shell script where I need to create an output log at the same time run it in the background? The catch is, I need to input a couple of parameters then enter a password.
For example I execute the shell script like so:
-bash-4.3$ ./tst.sh param1 param2 >> tst.log
Password for user mas:
I need to pass in (2) parameters, then prompted for a password:
./tsh.sh <param1> <param2>
This will work, but I have to keep the session open and I want it so it goes to the background or something similar where it will continue to run if my connection to the host fails..
If you want to run something that will survive if your connection fails you should run it in a screen or tmux session. You can use those to create sessions that you can disconnect from and reconnect to, and many other really cool things once you start really getting into them.
So if you ssh in and then run screen you'll still be at a bash prompt, but if you run a command then press ^a^d you will detach from that session. Everything running inside screen will keep going, and you'll be able to reconnect with screen -x later. You can have many screen sessions at the same time too, use screen -ls to see which are running then you can use screen -x <id> to reconnect to a particular one.

How to reconnect to accidentally disconnected ssh session WITHOUT screen or tmux

I know these kinds of questions have been asked for years, and the answer to them are often Screen or tmux.
I surely will use screen at beginning if I know I will leave the session for a long time, or the network is too bad to maintain a reliable connection.
The main problem is when I start some session and find it must last long later, or the connection just lost accidentally. In the later case, often when I start another session immediately, I can find the previous processes are not killed at that time, but I just have no way to reconnect to their terminal.
So I wonder if it is possible to prevent normal processes from killed even long time after accidentally disconnected SSH session. And the most important is I can reconnect to their terminals with out start them in Screen in advance.
If not, is is possible to move a already started bare ssh session into a new Screen session for later reconnect?
I don't believe it's possible without something like screen. Once your pseudo-TTY is lost I'm almost certain it can't be recovered from a different shell (at least not without some narly hacks).
As far as adding an existing process to a new screen I think that is possible. Try the instructions here:
http://monkeypatch.me/blog/move-a-running-process-to-a-new-screen-shell.html
The first thing to do is to suspend the process. In my case, Irssi can be suspended by typing Ctrl + Z.
Secondly, resume the process in background:
$ bg
Now, we will detach the process from its parent (the shell). So, when the parent process will be terminated, the child (Irssi) will be able to continue. For this, we use the disown builtin:
$ disown irssi
Launch a screen session:
$ screen
As we are in a screen session, we will retrieve the irssi process. To do so, we use the reptyr command which take a pid:
$ reptyr
To avoid the tedious pid research, we can use the pgrep command:
$ reptyr $(pgrep irssi)
Now the process is in a screen shell, we can safely detach our session and no longer worry about killing our X server or close our ssh connection.
You'll need reptyr for this.
OPTION 2:
I suspect you may be trying to solve the wrong problem. If your SSH connection is dropping, why not address that? You can set SSH to be incredibly tolerant of timeouts and disconnects by tweaking your connection settings.
On your client, in $HOME/.ssh/config add:
ServerAliveInterval 60
ServerAliveCountMax 5
Now your sessions won't timeout even if the server doesn't respond for 5 minutes.
Use ssh-tmux instead of tmux:
function ssh-tmux(){
if ! command -v autossh &> /dev/null; then echo "Install autossh"; fi
autossh -M 0 $* -t 'byobu || {echo "Install byobu-tmux on server..."} && bash'
}
I worked on a text file using nano and I got disconnected. After I logged in I saw the nano process from the previous session was still running, but I couldn't switch to that nano instance. So, I killed the nano process and then it created file named filename.save. Which had my changes from the first session.

Automate a Ruby command without it exiting

This hopefully should be an easy question to answer. I am attempting to have mumble-ruby run automatically I have everything up and running except after running this simple script it runs but ends. In short:
Running this from terminal I get "Press enter to terminate script" and it works.
Running this via a cronjob runs the script but ends it and runs cli.disconnect (I assume).
I want the below script to run automatically via a cronjob at a specified time and not end until the server shuts down.
#!/usr/bin/env ruby
require 'mumble-ruby'
cli = Mumble::Client.new('IP Address', Port, 'MusicBot', 'Password')
cli.connect
sleep(1)
cli.join_channel(5)
stream = cli.stream_raw_audio('/tmp/mumble.fifo')
stream.volume = 2.7
print 'Press enter to terminate script';
gets
cli.disconnect
Assuming you are on a Unix/Linux system, you can run it in a screen session. (This is a Unix command, not a scripting function.)
If you don't know what screen is, it's basically a "detachable" terminal session. You can open a screen session, run this script, and then detach from that screen session. That detached session will stay alive even after you log off, leaving your script running. (You can re-attach to that screen session later if you want to shut it down manually.)
screen is pretty neat, and every developer on Unix/Linux should be aware of it.
How to do this without reading any docs:
open a terminal session on the server that will run the script
run screen - you will now be in a new shell prompt in a new screen session
run your script
type ctrl-a then d (without ctrl; the "d" is for "detach") to detach from the screen (but still leave it running)
Now you're back in your first shell. Your script is still alive in your screen session. You can disconnect and the screen session will keep on trucking.
Do you want to get back into that screen and shut the app down manually? Easy! Run screen -r (for "reattach"). To kill the screen session, just reattach and exit the shell.
You can have multiple screen sessions running concurrently, too. (If there is more than one screen running, you'll need to provide an argument to screen -r.)
Check out some screen docs!
Here's a screen howto. Search "gnu screen howto" for many more.
Lots of ways to skin this cat... :)
My thought was to take your script (call it foo) and remove the last 3 lines. In your /etc/rc.d/rc.local file (NOTE: this applies to Ubuntu and Fedora, not sure what you're running - but it has something similar) you'd add nohup /path_to_foo/foo 2>&1 > /dev/null& to the end of the file so that it runs in the background. You can also run that command right at a terminal if you just want to run it and have it running. You have to make sure that foo is made executable with chmod +x /path_to_foo/foo.
Use an infinite loop. Try:
while running do
sleep(3600)
end
You can use exit to terminate when you need to. This will run the loop once an hour so it doesnt eat up processing time. An infinite loop before your disconnect method will prevent it from being called until the server shuts down.

Run Ruby script in the background

I have a Ruby script that I need to have running all the time in my Linux box. I tried nohup ruby ruby.rb& but it seems it doesn't work.
How can I have the script running in background?
Have a look at screen which is a command-line utility. Start it with
screen
You will get a new shell which is detached. Start your script there with
ruby whatever.rb
And watch it run. Then hit Ctrl-A Ctrl-D and you should be back at your original shell. You can leave the ssh session now, and the script will continue running. At a later time, login to your box and type
screen -r
and you should be back to the detached shell.
If you use screen more than once, you will have to select the screen session by pid which is not so comfortable. To simplify, you can do
screen -S worker
to start the session and
screen -r worker
to resume it.
Depending on your needs:
fork do
Process.setsid
sleep 5
puts "In daemon"
end
puts "In control script"
In real life you will have to reopen STDOUT/STDERR.

Resources