C'è un modo per eseguire 'schermo' in modalità di sola lettura?


16

Mi piacerebbe essere in grado di controllare l'avanzamento e l'output delle mie screensessioni esistenti , ma in sola lettura, in modo da evitare che qualcosa vada storto a causa di un errore dell'utente. C'è un modo per fare questo?

Risposte:


8

Sfortunatamente, penso che la risposta sia no. Il richiedente di questa domanda passato a tmux specificamente perché ha questa caratteristica (si passa il -rflag quando il collegamento), quindi se avete la possibilità di passare multiplexer è probabilmente la scelta migliore


3

Puoi provare:

aclchg username -w "#"

se corri screenin modalità multiutente (ma non ho dovuto fare nulla di speciale per farlo funzionare quando lo testavo come singolo utente collegato). Se è necessario accedere alla modalità multiutente, utilizzare multiuser on.

È possibile utilizzare *il nome utente per influire su tutti gli utenti.

Utilizzando +winvece di -wabilita la modalità di scrittura.

Da man screen:

aclchg elenco di
permessi di nomi utente chacl elenco di permessi di nomi utente

Modifica le autorizzazioni per un elenco di utenti separato da virgole. I bit di autorizzazione sono rappresentati come 'r', 'w' e 'x'. Il prefisso "+" concede l'autorizzazione, "-" la rimuove. Il terzo parametro è un elenco separato da virgole di comandi e / o finestre (specificato per numero o titolo). L'elenco speciale "#" fa riferimento a tutte le finestre "?" a tutti i comandi. se i nomi utente sono costituiti da un singolo '*', tutti gli utenti noti sono interessati. Un comando può essere eseguito quando l'utente ha il bit 'x' per esso. L'utente può digitare input in una finestra quando ha impostato il bit 'w' e nessun altro utente ottiene un writelock per questa finestra. Altri bit sono attualmente ignorati. Per ritirare il writelock da un altro utente nella finestra 2: 'aclchg username -w + w 2'. Per consentire l'accesso in sola lettura alla sessione: 'aclchg username -w "#"'. Non appena è noto che il nome di un utente viene visualizzato sullo schermo, può collegarsi alla sessione e (per impostazione predefinita) dispone delle autorizzazioni complete per tutti i comandi e le finestre. Il permesso di esecuzione per i comandi acl, `at 'e altri dovrebbero anche essere rimossi o l'utente potrebbe essere in grado di riottenere il permesso di scrittura. I diritti del nome utente speciale nessuno non possono essere modificati (vedere il comando "su"). 'Chacl' è un sinonimo di 'aclchg'. Solo modalità multiutente. e altri dovrebbero anche essere rimossi o l'utente potrebbe essere in grado di riottenere il permesso di scrittura. I diritti del nome utente speciale nessuno non possono essere modificati (vedere il comando "su"). 'Chacl' è un sinonimo di 'aclchg'. Solo modalità multiutente. e altri dovrebbero anche essere rimossi o l'utente potrebbe essere in grado di riottenere il permesso di scrittura. I diritti del nome utente speciale nessuno non possono essere modificati (vedere il comando "su"). 'Chacl' è un sinonimo di 'aclchg'. Solo modalità multiutente.


Mentre funziona, rende screenfacilmente accessibile ovunque la sessione dello schermo che sembra diversa da ciò che l'OP ha chiesto.
Stéphane Chazelas,

1
@StephaneChazelas: Non vedo alcuna indicazione nella domanda che l'OP sia preoccupato per la scrivibilità in altri casi di una sessione con moltiplicazioni. Inoltre, il aclcngcomando può specificare utenti particolari, comandi particolari e / o finestre particolari in modo che la granularità sia abbastanza buona. Quindi non è "ovunque".
In pausa fino a ulteriore avviso.

3

Ho trovato una soluzione abbastanza semplice che consente di monitorare l'output in modo sicuro.

Esegui i seguenti comandi immediatamente dopo aver effettuato l'accesso alla schermata:

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

Stacca la sessione con Ctrl-A de segui l'output dello script, ad esempio:

tail -f /tmp/10751.test

1

La mia attuale soluzione a questo è impostare Terminal View su ReadOnly .

Forse è troppo ovvio. Tuttavia, la domanda non ha richiesto una soluzione da screensola.


1
mi sta bene, con un emulatore di terminale che supporta la modalità di sola lettura. sfortunatamente, molti terminali non lo fanno (il terminale gnome / kde non iirc), ma alcuni lo fanno (come xfce4-terminal)
hanshenrik

0

ho scritto uno script php chiamato readscreenper ... allegare alle sessioni dello schermo in modalità di sola lettura. salvalo in/usr/bin/readscreen ed chmod 0555 /usr/bin/readscreeneseguilo e assicurati di avere php-cli installato con l'estensione php-pcntl, e puoi scrivere readscreenseguito da qualsiasi comando che useresti per connetterti con lo schermo normale, ad esempio:

readscreen -S foo -x

e sarai connesso alla sessione foo in sola lettura . si noti che non è ampiamente testato, ma sembra funzionare bene. codice sorgente dello schermo di lettura:

#!/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 ();
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.