Использование экрана GNU полностью прозрачно и автоматически
Экран потрясающий, конечно, но я не хочу об этом думать. Я часто сшиваю машину, начинаю делать кучу вещей, а потом думаю "черт возьми, мне жаль, что я не подумал начать сеанс экрана, прежде чем делать все, чтобы я мог снова подключиться к этому из дома позже".
Я бы хотел, чтобы экран автоматически запускался при каждом входе в систему.
И когда я отсоединяюсь, я хочу иметь возможность немедленно и просто подключиться без суеты с помощью "screen -ls" и "screen -dr".
У меня есть script, который реализует одно решение этой проблемы, которое я опубликую в качестве ответа. Мне интересно видеть другие подходы.
Ответы
Ответ 1
Используйте ssc
вместо ssh
. Если вы просто сделаете "ssc remote.com
", тогда он перечислит существующие сеансы экрана. Дайте ему третий аргумент, и он подключится к этому сеансу экрана или создаст его и подключится к нему. В любом случае, если вы отключитесь, вы можете просто "стрелка вверх", введите "в оболочку для повторного подключения". Требуется нулевое знание экрана!
Редактировать: Спасибо @klochner за расширение этого для обработки произвольных параметров ssh. Теперь вы можете использовать это как ssh!
#!/usr/bin/env perl
# Use 'ssc' (this script) instead of 'ssh' to log into a remote machine.
# Without an argument after the hostname it will list available screens.
# Add an argument after the hostname to attach to an existing screen, or
# specify a new screen. Eg, ssc remote.com foo
# The numbers in front of the screen tag can usually be ignored.
# ssh option parsing by @klochner
my $optstring = "";
while ($val = shift) {
if ($val =~ /^-\w$/) { $optstring .= " ".$val.(shift); }
elsif ($val =~ /^-\w+$/) { $optstring .= " ".$val; }
elsif ($machine) { $tag = $val; }
else { $machine = $val; }
}
if (!$machine) {
print "USAGE: ssc [ssh options] remote.com [screen name]\n";
} elsif (!$tag) {
@screens = split("\n", `ssh $optstring $machine screen -ls`);
for(@screens) {
if(/^\s*(\d+)\.(\S+)\s+\(([^\)]*)\)/) {
($num, $tag, $status) = ($1, $2, $3);
if($status =~ /attached/i) { $att{"$num.$tag"} = 1; }
elsif($status =~ /detached/i) { $att{"$num.$tag"} = 0; }
else { print "Couldn't parse this: $_\n"; }
# remember anything weird about the screen, like shared screens
if($status =~ /^(attached|detached)$/i) {
$special{"$num.$tag"} = "";
} else {
$special{"$num.$tag"} = "[$status]";
}
}
}
print "ATTACHED:\n";
for(sort { ($a=~/\.(\w+)/)[0] cmp ($b=~/\.(\w+)/)[0] } keys(%att)) {
($tag) = /\.(\w+)/;
print " $tag\t($_)\t$special{$_}\n" if $att{$_};
}
print "DETACHED:\n";
for(sort { ($a=~/\.(\w+)/)[0] cmp ($b=~/\.(\w+)/)[0] } keys(%att)) {
($tag) = /\.(\w+)/;
print " $tag\t($_)\t$special{$_}\n" unless $att{$_};
}
} else {
system("ssh $optstring -t $machine \"screen -S $tag -dr || screen -S $tag\"");
}
Btw, есть трюк для принудительного завершения сеанса ssh и возврата вашего локального терминала при отключении сетевого подключения:
https://superuser.com/questions/147873/ssh-sessions-in-xterms-freeze-for-many-minutes-whenever-they-disconnect
Ответ 2
есть autossh
, который автоматически восстанавливает отключенные ssh-сеансы.
Он поставляется с примером script, называемым rscreen
, который делает именно это. Это просто:
#!/bin/sh
autossh -M 0 -t $1 "screen -e^Aa -D -R"
Затем вам нужно переустановить свои пальцы, чтобы ввести rscreen hostname
вместо ssh hostname
Ответ 3
На самом деле экран устанавливает для переменной TERM значение 'screen'. Таким образом, script еще проще. Вот что я использую:
if [ "$TERM" != "screen" ]; then
screen -xRR
fi
Работает как шарм, -x
гарантирует, что даже если экран подключен где-то еще, я присоединяюсь к нему здесь. Таким образом, у меня есть только один экран, на котором я могу отслеживать все.
Ответ 4
ssh [email protected] -t 'screen -dRR'
Это приведет к перезагрузке/созданию сеанса экрана при подключении. Это делает именно то, что было запрошено, даже если оно переносит ответственность за нерест сеанса инициаторному клиенту. В идеале вам нужен какой-то процесс на сервере, управляющий тем, что будет представлено для подключения клиентов. Насколько я знаю, этого не существует. Никто не предложил идеальное решение в этой теме. Для меня это меньше "не идеально", чем для остальных. Никаких сценариев, ошибок, проблем с TTY, никаких плохих взаимодействий с другими командами ssh, нет возможности для бесконечных циклов, редактирования файлов и дополнительных пакетов.
Ответ 5
У меня есть следующее в моем .bashrc
if [ "$PS1" != "" -a "${_STARTED_SCREEN:-x}" = x -a "${SSH_TTY:-x}" ]
then
export _STARTED_SCREEN=1;
sleep 1
screen -RR && exit 0
# normally, execution of this rc script ends here...
echo "Screen failed! continuing with normal bash startup"
fi
Я нашел его в сети где-то некоторое время назад, не уверен, где.
Обновить Исправлена ошибка, отмеченная в комментариях. Спасибо Р. Пате
Ответ 6
Я использовал autossh, мне это очень полезно
Ответ 7
Возможно, поместите exec screen -dr
в ваш .login?
Ответ 8
Я использую mosh (мобильная оболочка). Он поддерживает ваше соединение, даже если вы переходите в спящий режим, отключаетесь от сети, меняете IP и т.д. Всякий раз, когда вы возвращаетесь, вы возвращаете свое соединение.
Ответ 9
Зависит от вашей оболочки, но как насчет .bashrc? (Если вы используете bash "screen -rd" )