31

I use Ubuntu 16.04 and I need the following tmux solution because I want to run a timeout process with sleep as in my particular case I wasn't satisfied from at and encountered a bug with nohup (when combining nohup-sleep). Now, tmux seems as best alternative as it has its own no-hangup mechanism and is actually working fine in manual usage (I ask the question only in regards to automizing the process I can already do manually with it).

What I need:

I need a way to do the following 3 actions, all in one operation:

  1. Attaching a new tmux session.
  2. Injecting a ready set of commands to that session, like (sleep 30m ; rm -rf dir_name ; exit). I would especially prefer a multi-line set, and not one long row.
  3. Executing the above command set the moment it was finished to be written as stdin in new tmux session.

In other words, I want to execute a code set in another tmux session that was specially created for that cause, but to do all in one operation.


Notes:

  • I aim to do all from my original working session (the one I work from most of the time). Generally, I have no intention to visit the newly created session, I just want to create it with its automatically executed code and that's it.

  • If possible, I would prefer an heredoc solution. I think it's most efficient.

3 Answers 3

49

If you put the code you want to execute in e.g. /opt/my_script.sh, it's very easy to do what you want:

tmux new-session -d -s "myTempSession" /opt/my_script.sh

This starts a new detached session, named "myTempSession", executing your script. You can later attach to it to check out what it's doing, by executing tmux attach-session -t myTempSession.

That is in my opinion the most straightforward and elegant solution. I'm not aware of any easy way of execute commands from stdin (read "from heredocs") with tmux. By hacking around you might even be able to do it, but it would still be (and look like) a hack.

For example, here's a hack that uses the command i suggested above to simulate the behaviour you want (= execute code in a new tmux session from a heredoc. No write occurs on the server's hard drive, as the temporary file is created /dev/shm, which is a tmpfs):

(
  cat >/dev/shm/my_script.sh &&
  chmod +x /dev/shm/my_script.sh &&
  tmux new-session -d '/dev/shm/my_script.sh; rm /dev/shm/my_script.sh'
) <<'EOF'
    echo "hacky, but works"
EOF
17
  • 1
    Dear Mario. Always a pleasure to read your answers. I am not sure if I understand correct, please tell me if I'm wrong: 1. There are two ways to do so, one involves first creating a temporary script (that contains the code) and execute it with creation and the second is an heredoc way. 2. If the second way works (when each echo row contains each code row of the heredoc) why should we see this as a hack if it's a Bash valid code? Maybe because rows of the heredoc are echoed and not executed regularly in heredocs?
    – user149572
    Jan 6, 2017 at 5:15
  • 3
    @Benia It's a hack since it only works on some Unix systems that have /dev/shm. It's also a hack since it's more complicated, difficult to read, to understand and to maintain than simply writing the script to an ordinary file and starting that with tmux.
    – Kusalananda
    Jan 6, 2017 at 8:30
  • 1
    As @Kusalananda explained, heredocs for code execution are bad practice in general. Altough ugly and unmantainable, it works, but it forces you to find roundabout way of doing otherwise very simple stuff...just compare the first and second code blocks in the answer: can you tell how it works? How long does it take you to do that? It's even more of a hack as tmux has no way of executing commands from stdin (save for even-more-hacky ways so ugly i won't even consider), so external scripts are the only (answer to the 1. of your question) way. Jan 6, 2017 at 11:51
  • 1
    Sorry, there was a mistake in the first sample (the "new-session" command is not implied if you use arguments). Now it's fixed. Jan 6, 2017 at 18:27
  • 1
    Now when I execute tmux new-session -d -s "myTempSession" /opt/my_script.sh it does not open a temporary file for me to paste the code... What I need is to open the script directly from current session, or at least something to move to the new session and then directly go back to the current session. BTW I plan to give bounty for all of your help as it is the least I can do to thank you and I could give bounty in 11 hours.
    – user149572
    Jan 7, 2017 at 3:37
3

Also see https://serverfault.com/questions/339390/run-command-in-detached-tmux-session for examples on using the send-keys command on a detached pane.

1

Mixing the above solution I came up with another way to achieve the same (assuming bash):

#!/bin/bash

wantTmuxExecute() {
   sleep 30m ;
   rm -rf dir_name ; 
   ...
}
# send to tmux
type wantTmuxExecute | tail -n +2 > /dev/shm/wantInTmux.sh

# execute tmux
tmux new-session -d 'source /dev/shm/wantInTmux.sh ; rm /dev/shm/wantInTmux.sh'
tmux send-keys 'wantTmuxExecute'
2
  • Why do you need the type wantTmuxExecute | tail -n +2 > /dev/shm/wantInTmux.sh line here?
    – a06e
    Apr 27, 2022 at 8:27
  • In bash, a type someFunction will print the code of someFunction, pipe this output to tail to remove lines and direct the output to a shared memory area /dev/shm to a file wantInTmux.sh. This shared memory will be available inside the tmux session. If you have that something already in another file and executable, do not need it.
    – JrBenito
    May 19, 2022 at 22:46

You must log in to answer this question.