Frage

We have an attended-upgrade script which launches apt-get update && apt-get upgrade simultaneously on all our administered systems. Ideally, we'd want to launch them all inside a screen session. When I do it like this:

File: upgrade.sh


for host in $ALLHOSTS
do
    some_commands_which_take_considerable_time
    screen -X screen sh -c "ssh $host \"apt-get update && apt-get upgrade\""
done

$ screen ./upgrade.sh

, it works, but as there are new windows arriving on the session, they are automatically being switched to. Instead, I'd rather have a version where the active window is fixed unless contained process quits or I switch manually using ^A n.

Bonus points if there is a possibility to preserve windows with exited processes, but keeping them separate from windows with active processes.

War es hilfreich?

Lösung 3

Thanks to CodeGnome, I'll probably go with tmux as I believe there is no way to do it with screen (that's unfortunate, really!).

To give a better sketch of how it can be used:

#!/bin/sh

tmux new-session -d -s active
tmux new-session -d -s inactive
tmux set-option -t active set-remain-on-exit on

for host in $ALLHOSTS
do
    tmux new-window -d -t active: -n upgrade-$host "
        ./do_upgrade_stuff.sh $host
        tmux move-window -s active:upgrade-$host -t inactive:
    "
done

Andere Tipps

You can do this with tmux. For example:

# Start a session named "apt-get" and leave it running in the background.
tmux session-new -d -s apt-get

# Preserve windows with inactive processes.
tmux set-option -t apt-get set-remain-on-exit on

# Start a new window without switching to it. You can also do this from
# within a running tmux session, not just outside of it.
tmux new-window -d -t apt-get -n upgrade-$host \
     "ssh $host 'apt-get update && apt-get upgrade'"

Note that you can have multiple windows with the same name, or modify the argument to the -n flag for unique names. The tmux application doesn't care.

As an example, you could name each window "upgrade," but that would make it difficult to identify your SSH sessions at a glance. Instead, this example appends the value of the host variable (populated by your for-loop) to each window name. This makes it easier to navigate, or to programmatically close windows you are no longer interested in. This is especially valuable when you have a lot of unclosed windows displaying terminated processes.

Overall, the syntax is a little cleaner and more intuitive than GNU screen's for this sort of task, but your mileage may vary.

W/r/t preserving windows after a subprocess exits, one possibility is to invoke the zombie command in your screen config file(s), which requires that you specify two keyboard characters that kill or resurrect the window, respectively. E.g.:

zombie KR

Then, K would kill a window whose subprocess has terminated, while R would attempt to relaunch the subprocess in the same window. Note that, in a zombie window, those keys are captured at the top level (i.e., do not precede them with your normal screen control character prefix sequence).

In order to prevent automatic switching to a newly created window, try altering your invocation of screen to something like the following:

screen -X eval 'screen sh -c "ssh $host \"apt-get update && apt-get upgrade\""' 'other'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top