Apakah ada cara untuk menjalankan 'layar' dalam mode baca-saja?

16

Saya ingin dapat memeriksa progres dan output dari screensesi saya yang ada , tetapi dengan cara read-only, untuk mencegah sesuatu dari kesalahan karena kesalahan pengguna. Apakah ada cara untuk melakukan ini?

Naftuli Kay
sumber

Jawaban:

8

Sayangnya, saya pikir jawabannya tidak. Penanya pertanyaan ini beralih ke tmux secara khusus karena memiliki fitur tersebut (Anda memberikan -rtanda saat melampirkan), jadi jika Anda memiliki opsi untuk beralih multiplexer, mungkin itu pilihan terbaik Anda.

Michael Mrozek
sumber
3

Anda dapat mencoba:

aclchg username -w "#"

jika Anda menjalankan screendalam mode multi-pengguna (tapi saya tidak perlu melakukan sesuatu yang khusus untuk membuatnya berfungsi ketika mengujinya sebagai pengguna tunggal yang dilampirkan). Jika Anda perlu masuk ke mode multiuser, gunakan multiuser on.

Anda dapat menggunakan *nama pengguna untuk mempengaruhi semua pengguna.

Menggunakan +walih-alih -wmengaktifkan mode tulis.

Dari man screen:

aclchg nama pengguna mengizinkan daftar
chacl nama pengguna mengizinkan daftar

Ubah izin untuk daftar pengguna yang dipisahkan koma. Bit izin direpresentasikan sebagai 'r', 'w' dan 'x'. Awalan '+' memberikan izin, '-' menghapusnya. Parameter ketiga adalah daftar perintah dan / atau jendela yang dipisahkan koma (ditentukan berdasarkan angka atau judul). Daftar khusus '#' mengacu pada semua jendela, '?' untuk semua perintah. jika nama pengguna terdiri dari satu '*', semua pengguna yang dikenal akan terpengaruh. Perintah dapat dieksekusi ketika pengguna memiliki bit 'x' untuk itu. Pengguna dapat mengetik input ke jendela ketika ia memiliki bit 'w' dan tidak ada pengguna lain yang mendapatkan writelock untuk jendela ini. Bit lain saat ini diabaikan. Untuk menarik writelock dari pengguna lain di jendela 2: 'aclchg username -w + w 2'. Untuk mengizinkan akses hanya baca ke sesi: 'aclchg nama pengguna -w "#"'. Segera setelah nama pengguna diketahui untuk disaring, ia dapat melampirkan ke sesi dan (per default) memiliki izin penuh untuk semua perintah dan jendela. Izin eksekusi untuk perintah acl, `at 'dan yang lainnya juga harus dihapus atau pengguna mungkin bisa mendapatkan kembali izin tertulis. Hak nama pengguna khusus tidak ada yang tidak dapat diubah (lihat perintah "su"). 'Chacl' adalah sinonim dengan 'aclchg'. Mode multi-pengguna saja. dan yang lainnya juga harus dihapus atau pengguna mungkin bisa mendapatkan kembali izin menulis. Hak nama pengguna khusus tidak ada yang tidak dapat diubah (lihat perintah "su"). 'Chacl' adalah sinonim dengan 'aclchg'. Mode multi-pengguna saja. dan yang lainnya juga harus dihapus atau pengguna mungkin bisa mendapatkan kembali izin menulis. Hak nama pengguna khusus tidak ada yang tidak dapat diubah (lihat perintah "su"). 'Chacl' adalah sinonim dengan 'aclchg'. Mode multi-pengguna saja.

Dijeda sampai pemberitahuan lebih lanjut.
sumber
Sementara itu berfungsi, itu membuat hanya screenbaca di mana saja sesi layar terpasang yang terlihat berbeda dari apa yang diminta OP.
Stéphane Chazelas
1
@StephaneChazelas: Saya tidak melihat indikasi apa pun dalam pertanyaan bahwa OP prihatin tentang kemampuan menulis dalam hal lain dari sesi yang dilipatgandakan. Selain itu, aclcngperintah tersebut dapat menentukan pengguna tertentu, perintah tertentu dan / atau jendela tertentu sehingga itu granularity cukup baik. Jadi itu bukan "di mana-mana".
Dijeda sampai pemberitahuan lebih lanjut.
3

Saya telah menemukan solusi yang cukup sederhana yang memungkinkan seseorang untuk memantau output dengan aman.

Jalankan perintah berikut segera setelah memasuki sesi layar:

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

Lepaskan sesi dengan Ctrl-A ddan ikuti output skrip, misalnya:

tail -f /tmp/10751.test
Menandai
sumber
1

Solusi saya saat ini adalah mengatur Tampilan Terminal menjadi ReadOnly .

Mungkin terlalu jelas. Namun, pertanyaan itu tidak membutuhkan solusi dengan screensendirinya.

sebkraemer
sumber
1
terlihat bagus untuk saya, dengan emulator terminal yang mendukung mode read-only. sayangnya, banyak terminal tidak (terminal gnome / kde tidak iirc), tetapi ada juga yang (seperti xfce4-terminal)
hanshenrik
0

saya menulis skrip php yang dipanggil readscreenuntuk ... melampirkan ke sesi layar dalam mode read-only. simpan /usr/bin/readscreendan jalankan chmod 0555 /usr/bin/readscreen, dan pastikan php-cli diinstal dengan ekstensi php-pcntl, dan Anda dapat menulis readscreendiikuti dengan perintah apa pun yang akan Anda gunakan untuk terhubung dengan layar normal, misalnya:

readscreen -S foo -x

dan Anda akan terhubung ke sesi foo dengan cara baca-saja . Perhatikan bahwa ini tidak diuji secara luas, tetapi tampaknya berfungsi dengan baik. kode sumber layar baca:

#!/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 ();
}
hanshenrik
sumber