Czy istnieje sposób na uruchomienie ekranu w trybie tylko do odczytu?


16

Chciałbym móc sprawdzać postęp i wyniki moich istniejących screensesji, ale tylko w trybie do odczytu, aby zapobiec wystąpieniu błędu z powodu błędu użytkownika. Czy jest na to sposób?

Odpowiedzi:


8

Niestety myślę, że odpowiedź brzmi „nie”. Pytający tego pytania przestawił się na tmux, ponieważ ma tę funkcję (przekazujesz -rflagę podczas dołączania), więc jeśli masz opcję przełączania multiplekserów, to prawdopodobnie najlepszy wybór


3

Możesz spróbować:

aclchg username -w "#"

jeśli działasz screenw trybie wielu użytkowników (ale nie musiałem robić nic specjalnego, aby działał podczas testowania go jako pojedynczy dołączony użytkownik). Jeśli musisz przejść do trybu wielu użytkowników, użyj multiuser on.

Możesz użyć *nazwy użytkownika, aby wpłynąć na wszystkich użytkowników.

Używanie +wzamiast -wwłącza tryb zapisu.

Od man screen:

aclchg lista
nazw użytkowników lista uprawnień chacl lista nazw użytkowników

Zmień uprawnienia dla listy użytkowników oddzielonych przecinkami. Bity uprawnień są reprezentowane jako „r”, „w” i „x”. Prefiks „+” przyznaje uprawnienie, „-” usuwa je. Trzeci parametr to rozdzielona przecinkami lista poleceń i / lub okien (określona liczbą lub tytułem). Specjalna lista „#” odnosi się do wszystkich okien, „?” do wszystkich poleceń. jeśli nazwy użytkowników składają się z jednego „*”, dotyczy to wszystkich znanych użytkowników. Polecenie można wykonać, gdy użytkownik ma do niego bit „x”. Użytkownik może wpisać dane wejściowe do okna, gdy ma ustawiony bit „w” i żaden inny użytkownik nie uzyska blokady zapisu dla tego okna. Inne bity są obecnie ignorowane. Aby wycofać writelock od innego użytkownika w oknie 2: „aclchg nazwa użytkownika -w + w 2”. Aby zezwolić na dostęp tylko do odczytu do sesji: 'aclchg nazwa użytkownika -w "#"'. Gdy tylko nazwa użytkownika będzie znana z ekranu, może dołączyć do sesji i (domyślnie) ma pełne uprawnienia do wszystkich poleceń i okien. Zezwolenie na wykonywanie poleceń acl, `at 'i innych również powinno zostać usunięte lub użytkownik może odzyskać uprawnienia do zapisu. Praw do specjalnej nazwy użytkownika nikt nie może zostać zmieniony (patrz polecenie „su”). „Chacl” jest synonimem „aclchg”. Tylko tryb wielu użytkowników. a inne również powinny zostać usunięte lub użytkownik może odzyskać uprawnienia do zapisu. Praw do specjalnej nazwy użytkownika nikt nie może zostać zmieniony (patrz polecenie „su”). „Chacl” jest synonimem „aclchg”. Tylko tryb wielu użytkowników. a inne również powinny zostać usunięte lub użytkownik może odzyskać uprawnienia do zapisu. Praw do specjalnej nazwy użytkownika nikt nie może zostać zmieniony (patrz polecenie „su”). „Chacl” jest synonimem „aclchg”. Tylko tryb wielu użytkowników.


Chociaż to działa, powoduje, że screentylko do odczytu jest dołączana wszędzie sesja ekranowa, która wygląda inaczej niż to, o co poprosił OP.
Stéphane Chazelas

1
@StephaneChazelas: Nie widzę żadnych wskazówek w pytaniu, że OP jest zaniepokojony możliwością zapisu w innych przypadkach wielokrotnie dołączanej sesji. Poza tym aclcngpolecenie może określać konkretnych użytkowników, określone polecenia i / lub określone okna, więc jest to dość drobna ziarnistość. Więc to nie jest „wszędzie”.
Wstrzymano do odwołania.

3

Znalazłem dość proste obejście, które pozwala bezpiecznie monitorować wyjście.

Uruchom następujące polecenia natychmiast po wejściu do sesji ekranowej:

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

Odłącz sesję Ctrl-A di śledź dane wyjściowe skryptu, np .:

tail -f /tmp/10751.test

1

Moje obecne rozwiązanie tego problemu polega na ustawieniu widoku terminala na Tylko do odczytu .

Może to zbyt oczywiste. Pytanie nie wymagało jednak rozwiązania screen.


1
wygląda mi dobrze, z emulatorem terminala obsługującym tryb tylko do odczytu. niestety wiele terminali nie działa (terminal gnome / kde nie działa), ale niektóre tak (jak xfce4-terminal)
hanshenrik

0

napisałem skrypt php o nazwie readscreen... dołączający do sesji ekranowych w trybie tylko do odczytu. zapisz go /usr/bin/readscreeni uruchom chmod 0555 /usr/bin/readscreen, i upewnij się, że masz zainstalowane php-cli z rozszerzeniem php-pcntl, a readscreennastępnie możesz napisać, a następnie dowolne polecenie, którego użyjesz do połączenia z normalnym ekranem, na przykład:

readscreen -S foo -x

i będziesz połączony z sesją foo w trybie tylko do odczytu . zwróć uwagę, że nie jest to dokładnie testowane, ale wydaje się działać dobrze. kod źródłowy ekranu odczytu:

#!/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 ();
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.