Run commands from a file in separate detached sessions [duplicate] - bash

I am trying to create a new tmux session and execute the command 'vagrant up'. 'Vagrant up' takes more than 3 hours so I want to detach the session so that I can come back later and check the status of that command by attaching back to the same session.
I followed the answer specified in the StackOverflow post to accomplish the same.
I am getting the error no session found. Here is my code:
$cat tmux_sh.sh
#!/bin/bash
echo "step 1"
tmux new-session -d -s rtb123 'vagrant up'
echo "step 2"
tmux detach -s rtb123
$./tmux_sh.sh
step 1
step 2
session not found: rtb123

Start a shell, and send vagrant up to it, so you can see the errors.
tmux new-session -d -s rtb123
tmux send-keys 'vagrant up' C-m
tmux detach -s rtb123
The C-m means hit return.

You are using the -d switch when creating the session. This means that the session will start detached, so you don't need to use the detach command. Besides, if your session is not running when you try to detach, it means that it no longer exists, so your command probably exited.

New, detached, named and with command executed in default shell:
tmux new-session -d -s apiserver 'java -cp /root/apiserver.jar com.package.EntryPoint'
To attach use:
tmux attach-session -t apiserver

Related

How to start tmux session on the server by ssh and execute script in the session

I have a program on the server, which execution should be initiated from the client by bash script with the use of ssh. Moreover, this script should open the tmux session on the server, run the program with some argument and terminate the session after program return.
I tried several solutions, but no one has been successful.
1)
#! /bin/bash
argument='12345678'
ssh user#host << EOF
tmux new-session -t session1
./program $argument
tmux kill-session -t session1
EOF
The program executes on the server, but without tmux session.
Output: "open terminal failed: not a terminal"
2)
#! /bin/bash
ssh user#host -t 'tmux new-session -t session1'
As minimum, this command open the session (actually don't know what is the construction ssh user#host -t '...' and how it works. If someone explains, I will be grateful) and I can type commands manually. But I don't know how to make server run my program using the script as I plan. Please help me to find solution.
I think you want to create a "detached" tmux session, then use tmux send-keys to send command instructions to the session. Also, I would use the full path to program. E.g. something like this
ssh user#host << EOF
tmux new-session -t session1 -d
tmux send-keys -t session1 "/path/to/the/program $argument" C-m
tmux kill-session -t session1
EOF
Tell tmux to run the program for you.
ssh user#host "tmux new-session -t session1 './program \"$argument\"'"
This runs program instead of a shell in the (only) window of the new session. When the program exits, the window is closed and along with it the session ends. (Quoting can get a bit hairy, so I'm calling that out-of-scope for this question.)
You can start a new tmux session in detached mode and then send commands with tmux send-keys command:
#! /bin/bash
argument='12345678'
ssh user#host << EOF
tmux new-session -t session1 -d
tmux send-keys -t session1:1 "./program $argument && tmux -d" ENTER
EOF

Prevent tmux from exiting when script finishes

I'd like to prevent tmux from exiting automatically when the script finishes. For example, I have a command something like this(below), this does run a server for an app, but sometimes this unexpectedly exits with an error. When that happens, I'm unable to check what was wrong with the code, command.
tmux new-session -d -s "visited" 'bash -ic "visited --server"';
Following one is a simplified command of what I'd like to do.
tmux new-session -d -s "pwd" 'bash -c pwd' # but actually I need to load .bashrc
tmux a -t pwd # this should attach to the shell, but in my environment this does show "can't find session pwd" since the shell is already exited
I read a github issue and tried to add set exit-empty off to ~/.tmux.conf and restart the server tmux kill-server and re-tried the above, but seemed it doesn't work.
Just let tmux create a normal session and inject the keystrokes:
tmux new-session -d -s pwd
tmux send-keys pwd C-m
tmux a -t pwd
If you end your statement with && bash then it will drop you into a shell when completed succesful. If you want to do that only when command fails then instead use || bash.
E.g.
# Drops you into a shell if it fails, otherwise closes the window
tmux new-session -d -s "visited" 'bash -ic "visited --server" || bash';
# Drops you into a shell when finished successful, otherwise closes window.
tmux new-session -d -s "visited" 'bash -ic "visited --server" && bash';
# Always drops you into a shell when done.
tmux new-session -d -s "visited" 'bash -ic "visited --server" || bash && bash';

How to tell tmux when creating a new detached session to issue afterwards another tmux command

In my normal shell I create tmux sessions for running in the background with
tmux new-session -d -s my-session my-script.sh (1)
Now I want to add logging of all output via pipe-pane to the session. I know how to do this in a not-detached session (when being inside tmux):
Ctrl-B : pipe-pane -o 'cat >>~/tmp/output.log' (2)
But how can I tell tmux on creation of a detached session -- via (1) -- to add straight away the pipe-pane tmux command?
I basically look for a way in my normal shell to create detached tmux sessions with logging. - I am using tmux 1.6.
You can always combine the two commands into one tmux command (I dont have tmux 1.6 to test this on but it works for 2.2):
tmux new-session -d -s my-session my-script.sh \; pipe-pane -o 'cat >>~/tmp/output.log'
If you were using tmux 2.9 or later you can set a hook to run a command when a new session starts. Put in your ~/.tmux.conf
set-hook -g session-created "pipe-pane -o 'cat >>~/tmp/output.log'"
To cope with many sessions, you might include the session name in the filename, e.g. output.#{session_name}.log.

Starting a new tmux session and detaching it, all inside a shell script

I am trying to create a new tmux session and execute the command 'vagrant up'. 'Vagrant up' takes more than 3 hours so I want to detach the session so that I can come back later and check the status of that command by attaching back to the same session.
I followed the answer specified in the StackOverflow post to accomplish the same.
I am getting the error no session found. Here is my code:
$cat tmux_sh.sh
#!/bin/bash
echo "step 1"
tmux new-session -d -s rtb123 'vagrant up'
echo "step 2"
tmux detach -s rtb123
$./tmux_sh.sh
step 1
step 2
session not found: rtb123
Start a shell, and send vagrant up to it, so you can see the errors.
tmux new-session -d -s rtb123
tmux send-keys 'vagrant up' C-m
tmux detach -s rtb123
The C-m means hit return.
You are using the -d switch when creating the session. This means that the session will start detached, so you don't need to use the detach command. Besides, if your session is not running when you try to detach, it means that it no longer exists, so your command probably exited.
New, detached, named and with command executed in default shell:
tmux new-session -d -s apiserver 'java -cp /root/apiserver.jar com.package.EntryPoint'
To attach use:
tmux attach-session -t apiserver

bash scripting tmux, multiple detach/attach

I have a process I want to monitor by tail -f on several output files in different directories. I can use a bash script start tmux as a detached session, create multiple panes, change to the top directory and reattach. This all works. My problem comes when I want the script to send more commands later. Is there some reason why once I attach, my script can't send commands or detach/reattach later? The reason to do more commands is that some files take 45 seconds to be created before I can tail them.
My example looks like
#!/bin/bash
# this depends on some settings from my ~/.tmux.conf
TopLevel='/tsload'
SimDir=`ls -d $TopLevel/SIM_ISS*`
# create and detach session
tmux new-session -s simwatch -n Sim_Watch -d
# make left & right panes, only 1 window
tmux split-window -h -t simwatch
# change to toplevel dir
tmux send-keys -t simwatch:1.1 "cd $SimDir" C-m
tmux send-keys -t simwatch:1.2 "cd $SimDir" C-m
tmux attach -t simwatch
At this point my script fails when I try to have it do more. I've also tried 'tmux detach -t simwatch' issue commands and reattach but they don't take effect.
Not very familiar with tmux, but from my experiment with your script, it looks like that tmux 'attach -t simwatch' is a blocking operation, i.e. it starts and will end once you detach/exit from the session, which is when the script will continue.
Regarding the issue with the files that appear later, if you know their paths, you can try to follow them with "tail -F", which will wait for the files to appear.
tail --follow=name --retry missing_file

Resources