Existe uma maneira de executar 'screen' no modo somente leitura?

12

Gostaria de poder verificar o progresso e a saída das minhas screen sessões existentes, mas de uma forma só de leitura, para impedir que algo dê errado devido a um erro do utilizador. Existe uma maneira de fazer isso?

    
por Naftuli Kay 25.05.2011 / 22:17

5 respostas

7

Infelizmente, acho que a resposta é não. O consulente de esta questão mudou para < href="https://tmux.github.io/"> tmux especificamente porque tem esse recurso (você passa o -r flag ao anexar), então se você tem a opção de trocar multiplexadores é provavelmente sua melhor escolha

    
por 25.05.2011 / 22:24
3

Você pode tentar:

aclchg username -w "#"

se você executar screen no modo multiusuário (mas não precisei fazer nada especial para que funcionasse ao testá-lo como um único usuário conectado). Se você precisar entrar no modo multiusuário, use multiuser on .

Você pode usar * para o nome de usuário para afetar todos os usuários.

Usar +w em vez de -w ativa o modo de gravação.

Em man screen :

aclchg usernames permbits list
chacl usernames permbits list

Change permissions for a comma separated list of users. Permission bits are represented as 'r', 'w' and 'x'. Prefixing '+' grants the permission, '-' removes it. The third parameter is a comma separated list of commands and/or windows (specified either by number or title). The special list '#' refers to all windows, '?' to all commands. if usernames consists of a single '*', all known users are affected. A command can be executed when the user has the 'x' bit for it. The user can type input to a window when he has its 'w' bit set and no other user obtains a writelock for this window. Other bits are currently ignored. To withdraw the writelock from another user in window 2: 'aclchg username -w+w 2'. To allow read-only access to the session: 'aclchg username -w "#"'. As soon as a user's name is known to screen he can attach to the session and (per default) has full permissions for all command and windows. Execution permission for the acl commands, 'at' and others should also be removed or the user may be able to regain write permission. Rights of the special username nobody cannot be changed (see the "su" command). 'Chacl' is a synonym to 'aclchg'. Multi user mode only.

    
por 22.01.2013 / 22:46
2

Eu encontrei uma solução bastante simples que permite monitorar a saída com segurança.

Execute os seguintes comandos imediatamente após entrar na sessão de tela:

echo /tmp/$STY
touch /tmp/$STY
chmod 0600 /tmp/$STY
script -a -f /tmp/$STY

Separe a sessão com Ctrl-A d e siga a saída do script, por exemplo:

tail -f /tmp/10751.test
    
por 12.02.2015 / 22:23
1

Minha solução atual para isso é definir a visualização de terminal como ReadOnly .

Talvez seja óbvio demais. No entanto, a questão não exigiu uma solução por screen .

    
por 04.10.2018 / 08:58
0

Eu escrevi um script php chamado readscreen para ... anexar a sessões de tela no modo somente leitura. salve-o em /usr/bin/readscreen e execute 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 por qualquer comando que você usasse para conectar-se à tela normal, por exemplo :

readscreen -S foo -x

e você estará conectado à sessão foo de maneira somente leitura . note que ele não é extensivamente testado, mas parece funcionar bem. código fonte 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, "" ); // 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 ();
}
    
por 09.12.2018 / 01:11

Tags