Чи є спосіб запустити "екран" у режимі лише для читання?


16

Я хотів би мати можливість перевірити хід і результати своїх існуючих screenсеансів, але лише для читання, щоб не допустити того, що щось піде не так через помилку користувача. Чи є спосіб це зробити?

Відповіді:


8

На жаль, я думаю, що відповідь - ні. Автор запитання перейшов до tmux спеціально, оскільки він має цю функцію (ви передаєте-r прапор під час приєднання), тому, якщо у вас є можливість переключити мультиплексори, це, мабуть, найкращий вибір


3

Ви можете спробувати:

aclchg username -w "#"

якщо ви працюєте screenв багатокористувацькому режимі (але мені не довелося робити нічого особливого, щоб він працював при тестуванні його як одного приєднаного користувача). Якщо вам потрібно перейти в режим багатокористувача, використовуйте multiuser on.

Ви можете використовувати *ім'я користувача, щоб вплинути на всіх користувачів.

Використання +wзамість -wвключеного режиму запису.

Від man screen:

список
імен користувачів perlits aclchg список імен користувачів chacl

Змінення дозволів для списку користувачів, розділених комами. Біти дозволу представлені як 'r', 'w' та 'x'. Префіксація "+" надає дозвіл, "-" видаляє його. Третій параметр - це розділений комами список команд та / або вікон (заданий або номером, або заголовком). Спеціальний список "#" стосується всіх вікон, "?" до всіх команд. якщо імена користувачів складаються з одного "*", це впливає на всіх відомих користувачів. Команда може бути виконана, коли користувач має для неї біт 'x'. Користувач може ввести вхід у вікно, коли у нього встановлено біт 'w', і ніхто інший користувач не отримує блокування запису для цього вікна. Інші біти наразі ігноруються. Щоб вивести блокування запису від іншого користувача у вікні 2: 'ім'я користувача aclchg -w + w 2'. Щоб дозволити доступ до сеансу лише для читання: 'ім'я користувача aclchg -w "#"'. Як тільки ім'я користувача з’явиться на екрані, він може приєднатися до сеансу і (за замовчуванням) має повні дозволи для всіх команд та вікон. Дозвіл на виконання команд acl, `at 'та інших також має бути видалений, або користувач може мати можливість відновити дозвіл на запис. Права спеціального імені користувача ніхто не може бути змінений (див. Команду "su"). 'Chacl' - синонім 'aclchg'. Тільки багатокористувацький режим. а також інші повинні бути видалені або користувач може отримати можливість дозволу на запис. Права спеціального імені користувача ніхто не може бути змінений (див. Команду "su"). 'Chacl' - синонім 'aclchg'. Тільки багатокористувацький режим. а також інші повинні бути видалені або користувач може отримати можливість дозволу на запис. Права спеціального імені користувача ніхто не може бути змінений (див. Команду "su"). 'Chacl' - синонім 'aclchg'. Тільки багатокористувацький режим.


Хоча це працює, він робить лише screenчитати скрізь скріплений сеанс екрану, який виглядає як інакше, ніж запитував ОП.
Стефан Шазелас

1
@StephaneChazelas: Я не бачу жодних вказівок у питанні, що ОП стурбована робочою здатністю в інших випадках сеансу, що додається багато разів. Крім того, aclcngкоманда може визначати конкретних користувачів, конкретні команди та / або конкретні вікна, так що це досить точна деталізація. Тож це не «скрізь».
Призупинено до подальшого повідомлення.

3

Я знайшов досить просту обробку, яка дозволяє спокійно контролювати вихід.

Виконайте наступні команди відразу після виходу на екранне сеанс:

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

Від'єднайте сеанс за допомогою Ctrl-A dта слідкуйте за вихідним сценарієм, наприклад:

tail -f /tmp/10751.test

1

Моє поточне рішення для цього - встановити перегляд терміналу на ReadOnly .

Можливо, це занадто очевидно. Однак питання не потребувало вирішення screenсамостійно.


1
мені добре виглядає з термінальним емулятором, який підтримує режим лише для читання. на жаль, багато терміналів не робить (gnome / kde термінал не iirc), але деякі роблять (як xfce4-terminal)
hanshenrik

0

Я написав скрипт на PHP, який закликав readscreen... приєднувати до сеансів на екрані в режимі лише для читання. збережіть його /usr/bin/readscreenта запустіть chmod 0555 /usr/bin/readscreen, і переконайтеся, що встановлено php-cli з розширенням php-pcntl, і ви можете написати, readscreenза яким слід виконувати будь-яку команду, яку ви використовуєте для підключення до звичайного екрану, наприклад:

readscreen -S foo -x

і ви будете підключені до foo сесії в режимі лише для читання . зауважте, що він недостатньо перевірений, але, здається, працює добре. вихідний код readscreen:

#!/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 ();
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.