Я хотел бы иметь возможность проверять ход и результаты моих существующих screen
сеансов, но только для чтения, чтобы не допустить неправильной работы из-за ошибки пользователя. Есть ли способ сделать это?
Я хотел бы иметь возможность проверять ход и результаты моих существующих screen
сеансов, но только для чтения, чтобы не допустить неправильной работы из-за ошибки пользователя. Есть ли способ сделать это?
Ответы:
К сожалению, я думаю, что ответ - нет. Ответчик на этот вопрос переключился на tmux именно потому, что он имеет эту функцию (вы устанавливаете -r
флаг при подключении), поэтому, если у вас есть возможность переключать мультиплексоры, это, вероятно, ваш лучший выбор
Можешь попробовать:
aclchg username -w "#"
если вы работаете screen
в многопользовательском режиме (но мне не нужно было делать ничего особенного, чтобы заставить его работать при тестировании как однопользовательский пользователь). Если вам нужно войти в многопользовательский режим, используйте multiuser on
.
Вы можете использовать *
для имени пользователя, чтобы повлиять на всех пользователей.
Использование +w
вместо -w
включает режим записи.
От man screen
:
список
разрешений userls aclchg список разрешений usernames chaclИзменить разрешения для списка пользователей через запятую. Биты разрешения представлены как 'r', 'w' и 'x'. Префикс «+» дает разрешение, «-» удаляет его. Третий параметр - это список команд и / или окон, разделенных запятыми (указывается либо номером, либо названием). Специальный список «#» относится ко всем окнам «?» на все команды. если имена пользователей состоят из одного '*', затрагиваются все известные пользователи. Команда может быть выполнена, когда у пользователя есть бит «x». Пользователь может вводить данные в окно, когда у него установлен бит w, и никакой другой пользователь не получает блокировку записи для этого окна. Другие биты в настоящее время игнорируются. Чтобы снять блокировку записи с другого пользователя в окне 2: «aclchg username -w + w 2». Чтобы разрешить доступ только для чтения к сеансу: 'aclchg username -w "#"'. Как только имя пользователя известно на экране, он может присоединиться к сеансу и (по умолчанию) имеет полные разрешения для всех команд и окон. Разрешение на выполнение команд acl, `at 'и других также должно быть удалено, иначе пользователь сможет восстановить разрешение на запись. Права специального имени пользователя никто не может быть изменен (см. Команду «su»). «Chacl» является синонимом «aclchg». Только многопользовательский режим. и другие также должны быть удалены, иначе пользователь сможет восстановить разрешение на запись. Права специального имени пользователя никто не может быть изменен (см. Команду «su»). «Chacl» является синонимом «aclchg». Только многопользовательский режим. и другие также должны быть удалены, иначе пользователь сможет восстановить разрешение на запись. Права специального имени пользователя никто не может быть изменен (см. Команду «su»). «Chacl» является синонимом «aclchg». Только многопользовательский режим.
aclcng
команда может указывать конкретных пользователей, конкретные команды и / или определенные окна, так что это довольно хорошая детализация. Так что это не "везде".
Я нашел довольно простой обходной путь, который позволяет безопасно контролировать вывод.
Выполните следующие команды сразу после входа в сеанс экрана:
echo /tmp/$STY
touch /tmp/$STY
chmod 0600 /tmp/$STY
script -a -f /tmp/$STY
Отключите сеанс Ctrl-A dи следуйте выводу скрипта, например:
tail -f /tmp/10751.test
Мое текущее решение для этого состоит в том, чтобы установить Terminal View на ReadOnly .
Может быть, это слишком очевидно. Однако вопрос сам по себе не требовал решения screen
.
я написал скрипт php, который называется readscreen
... прикреплять к сеансам экрана в режиме только для чтения. сохраните его /usr/bin/readscreen
и запустите chmod 0555 /usr/bin/readscreen
, убедитесь, что у вас установлен php-cli с расширением php-pcntl, и вы можете написать readscreen
любую команду, которую вы используете для подключения к обычному экрану, например:
readscreen -S foo -x
и вы будете подключены к сессии foo только для чтения . обратите внимание, что он не был тщательно протестирован, но, кажется, работает нормально. читать исходный код:
#!/usr/bin/env php
<?php
declare(ticks = 1);
init_signals ();
$args = $argv;
unset ( $args [0] );
$args = implode ( " ", array_map ( 'escapeshellarg', $args ) );
// var_dump ( $argc, $argv, $args );
$cmd = "screen {$args}";
echo "executing cmd: $cmd\n";
$descriptorspec = array (
0 => array (
"pipe",
"rb"
) // stdin
);
$cwd = NULL;
$env = NULL;
global $screen;
$screen = proc_open ( "script --quiet --return --command " . escapeshellarg ( $cmd )." /dev/null", $descriptorspec, $pipes, $cwd, $env );
global $screen_stdin;
$screen_stdin = $pipes [0];
if (false === $screen) {
echo ("error: failed creating screen process: ");
var_dump ( error_get_last () );
die ( 1 );
}
//fclose(STDIN);
while ( 1 ) {
//echo ".";
sleep ( 1 );
if (! proc_get_status ( $screen ) ['running']) {
echo "error: screen stopped.\n";
cleanup ();
die ( 1 );
}
}
function cleanup() {
global $screen;
global $screen_stdin;
echo "detaching from screen. (running cleanup() )\n";
fwrite ( $screen_stdin, "\01" ); // equivalent of ctrl+AD apparently.
fclose ( $screen_stdin );
$exited = false;
// give it a few seconds to exit itself before killing it
for($i = 0; $i < 3; ++ $i) {
if (! proc_get_status ( $screen ) ['running']) {
$exited = true;
break;
}
sleep ( 1 );
}
if (! $exited) {
echo "Warning: screen did not exit gracefully, killing it now..";
proc_terminate ( $screen, SIGKILL );
while ( proc_get_status ( $screen ) ['running'] ) {
echo ".";
sleep ( 1 );
}
echo "killed.";
}
proc_close ( $screen );
}
function init_signals() {
global $signals;
// all signals that cause termination by default.
$signals = [
"SIGABRT",
"SIGALRM",
"SIGFPE",
"SIGHUP",
"SIGILL",
"SIGINT",
// "SIGKILL",
"SIGPIPE",
"SIGQUIT",
"SIGSEGV",
"SIGTERM",
"SIGUSR1",
"SIGUSR2",
"SIGBUS",
"SIGPOLL",
"SIGPROF",
"SIGSYS",
"SIGTRAP",
"SIGVTALRM",
"SIGXCPU",
"SIGXFSZ"
];
$signals_new = [ ];
foreach ( $signals as $key => $signal ) {
$tmp = constant ( $signal );
if ($tmp === null) {
fprintf ( STDERR, "warning: unknown signal \"%s\", may not be able to handle it without passing it to screen...\n", $singal );
unset ( $signals [$key] );
continue;
}
$signals_new [$signal] = $tmp;
}
$signals = $signals_new;
unset ( $signals_new );
foreach ( $signals as $num ) {
pcntl_signal ( $num, "signal_handler" );
}
}
function signal_handler($signo, $siginfo) {
global $signals;
$sname = array_search ( $signo, $signals, false );
if ($sname === false) {
$sname = "unknown signal";
}
echo "\n\nerror: got signal " . $signo . " (" . $sname . "), exiting screen session & returning.\n";
var_dump ( $siginfo );
cleanup ();
die ();
}
screen
readonly везде, где присоединяется сеанс экрана, что, похоже, отличается от того, что запрашивал OP.