Eu gostaria de poder verificar o progresso e a saída das minhas screen
sessões existentes , mas de maneira somente leitura, para impedir que algo dê errado devido a erro do usuário. Existe uma maneira de fazer isso?
Eu gostaria de poder verificar o progresso e a saída das minhas screen
sessões existentes , mas de maneira somente leitura, para impedir que algo dê errado devido a erro do usuário. Existe uma maneira de fazer isso?
Respostas:
Infelizmente, acho que a resposta é não. O autor desta pergunta mudou para o tmux especificamente porque possui esse recurso (você passa a -r
bandeira ao anexar); portanto, se você tiver a opção de alternar multiplexadores, é provavelmente a melhor escolha
Podes tentar:
aclchg username -w "#"
se você executar screen
no modo multiusuário (mas não precisei fazer nada de especial para fazê-lo funcionar ao testá-lo como um único usuário conectado). Se você precisar entrar no modo multiusuário, use multiuser on
.
Você pode usar *
o nome de usuário para afetar todos os usuários.
Usar em +w
vez de -w
ativa o modo de gravação.
De man screen
:
aclchg lista de
permbits de nomes de usuário chacl lista de permbits de nomes de usuárioAltere as permissões para uma lista de usuários separados por vírgula. Os bits de permissão são representados como 'r', 'w' e 'x'. O prefixo '+' concede a permissão, '-' a remove. O terceiro parâmetro é uma lista separada por vírgula de comandos e / ou janelas (especificada por número ou título). A lista especial '#' refere-se a todas as janelas, '?' para todos os comandos. se os nomes de usuário consistirem em um único '*', todos os usuários conhecidos serão afetados. Um comando pode ser executado quando o usuário possui o bit 'x'. O usuário pode digitar a entrada para uma janela quando tiver o bit 'w' definido e nenhum outro usuário obtiver um bloqueio de gravação para esta janela. Outros bits são atualmente ignorados. Para retirar o writelock de outro usuário na janela 2: 'aclchg username -w + w 2'. Para permitir acesso somente leitura à sessão: 'aclchg username -w "#"'. Assim que o nome do usuário é conhecido na tela, ele pode se conectar à sessão e (por padrão) tem permissões totais para todos os comandos e janelas. A permissão de execução para os comandos acl, `at 'e outros também deve ser removida ou o usuário poderá recuperar a permissão de gravação. Direitos do nome de usuário especial ninguém pode ser alterado (consulte o comando "su"). 'Chacl' é sinônimo de 'aclchg'. Somente modo multiusuário. e outros também devem ser removidos ou o usuário poderá recuperar a permissão de gravação. Direitos do nome de usuário especial ninguém pode ser alterado (consulte o comando "su"). 'Chacl' é sinônimo de 'aclchg'. Somente modo multiusuário. e outros também devem ser removidos ou o usuário poderá recuperar a permissão de gravação. Direitos do nome de usuário especial ninguém pode ser alterado (consulte o comando "su"). 'Chacl' é sinônimo de 'aclchg'. Somente modo multiusuário.
aclcng
comando pode especificar usuários específicos, comandos específicos e / ou janelas específicas, de modo que é uma granularidade bastante fina. Então, isso não está "em todo lugar".
Eu encontrei uma solução alternativa bastante simples que permite monitorar a saída com segurança.
Execute os seguintes comandos imediatamente após entrar na sessão da tela:
echo /tmp/$STY
touch /tmp/$STY
chmod 0600 /tmp/$STY
script -a -f /tmp/$STY
Desanexe a sessão Ctrl-A de siga a saída do script, por exemplo:
tail -f /tmp/10751.test
Minha solução atual para isso é definir o Terminal View como ReadOnly .
Talvez seja muito óbvio. No entanto, a pergunta não exigia uma solução por screen
si só.
eu escrevi um script php chamado readscreen
para ... anexar a sessões de tela no modo somente leitura. salve-o /usr/bin/readscreen
e execute-o chmod 0555 /usr/bin/readscreen
e certifique-se de ter o php-cli instalado com a extensão php-pcntl, e você pode escrever readscreen
seguido de qualquer comando que usaria para conectar-se à tela normal, por exemplo:
readscreen -S foo -x
e você estará conectado à sessão foo somente leitura . observe que não foi extensivamente testado, mas parece funcionar bem. código fonte da tela de leitura:
#!/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
somente leitura em todos os lugares em que a sessão de tela é anexada, o que parece ser diferente do que o OP pediu.