มีวิธีเรียกใช้ 'หน้าจอ' ในโหมดอ่านอย่างเดียวหรือไม่


16

ฉันต้องการที่จะสามารถตรวจสอบความคืบหน้าและการส่งออกของเซสชั่นที่มีอยู่ของฉันscreenแต่ในรูปแบบอ่านอย่างเดียวเพื่อป้องกันไม่ให้บางสิ่งบางอย่างผิดปกติเนื่องจากข้อผิดพลาดของผู้ใช้ มีวิธีทำเช่นนี้หรือไม่?

คำตอบ:


8

น่าเสียดายที่ฉันคิดว่าคำตอบคือไม่ ผู้ถามของคำถามนี้เปลี่ยนไปเป็นtmuxโดยเฉพาะเพราะมันมีคุณสมบัตินั้น (คุณผ่านการ-rตั้งค่าสถานะเมื่อแนบ) ดังนั้นหากคุณมีตัวเลือกในการสลับมัลติเพล็กเซอร์มันอาจเป็นทางเลือกที่ดีที่สุดของคุณ


3

คุณสามารถลอง:

aclchg username -w "#"

ถ้าคุณทำงานscreenในโหมดผู้ใช้หลายคน (แต่ฉันไม่ต้องทำอะไรเป็นพิเศษเพื่อให้มันทำงานได้เมื่อทดสอบว่าเป็นผู้ใช้ที่ต่อพ่วงเดียว) multiuser onหากคุณไม่จำเป็นต้องเข้าสู่โหมดผู้ใช้หลายคนใช้

คุณสามารถใช้*ชื่อผู้ใช้เพื่อส่งผลกระทบต่อผู้ใช้ทั้งหมด

การใช้+wแทนที่จะ-wเปิดใช้งานโหมดการเขียน

จากman screen:

aclchg ชื่อผู้ใช้รายการ permbits ชื่อ
ผู้ใช้ chacl รายการ permbits

เปลี่ยนการอนุญาตสำหรับรายการผู้ใช้ที่คั่นด้วยเครื่องหมายจุลภาค บิตการอนุญาตถูกแสดงเป็น 'r', 'w' และ 'x' คำนำหน้า '+' ให้สิทธิ์อนุญาต '-' ลบออก พารามิเตอร์ที่สามคือรายการคำสั่งและ / หรือ windows ที่คั่นด้วยเครื่องหมายจุลภาค (ระบุด้วยหมายเลขหรือชื่อเรื่อง) รายการพิเศษ '#' หมายถึงหน้าต่างทั้งหมด, '?' ไปยังคำสั่งทั้งหมด หากชื่อผู้ใช้ประกอบด้วย '*' ผู้ใช้ที่รู้จักทั้งหมดจะได้รับผลกระทบ คำสั่งสามารถดำเนินการได้เมื่อผู้ใช้มีบิต 'x' ผู้ใช้สามารถพิมพ์อินพุตไปยังหน้าต่างเมื่อเขาได้ตั้งค่าบิต 'w' และไม่มีผู้ใช้รายอื่นได้รับ writelock สำหรับหน้าต่างนี้ บิตอื่น ๆ จะถูกละเว้นในขณะนี้ หากต้องการถอน writelock จากผู้ใช้รายอื่นในหน้าต่าง 2: 'aclchg ชื่อผู้ใช้ -w + w 2' หากต้องการอนุญาตให้เข้าถึงเซสชันแบบอ่านอย่างเดียว: 'aclchg username -w "#"' ทันทีที่ทราบว่ามีชื่อผู้ใช้ในหน้าจอผู้ใช้สามารถแนบกับเซสชันและ (ต่อค่าเริ่มต้น) มีสิทธิ์แบบเต็มสำหรับคำสั่งและหน้าต่างทั้งหมด สิทธิ์ดำเนินการสำหรับคำสั่ง acl `ที่ 'และอื่น ๆ ก็ควรจะถูกลบออกหรือผู้ใช้อาจจะสามารถได้รับอนุญาตเขียน สิทธิ์ของชื่อผู้ใช้พิเศษไม่สามารถเปลี่ยนแปลงได้ (ดูคำสั่ง "su") 'Chacl' เป็นชื่อพ้องของ 'aclchg' โหมดผู้ใช้หลายคนเท่านั้น และคนอื่น ๆ ก็ควรจะถูกลบออกหรือผู้ใช้อาจจะได้รับอนุญาตเขียน สิทธิ์ของชื่อผู้ใช้พิเศษไม่สามารถเปลี่ยนแปลงได้ (ดูคำสั่ง "su") 'Chacl' เป็นชื่อพ้องของ 'aclchg' โหมดผู้ใช้หลายคนเท่านั้น และคนอื่น ๆ ก็ควรจะถูกลบออกหรือผู้ใช้อาจจะได้รับอนุญาตเขียน สิทธิ์ของชื่อผู้ใช้พิเศษไม่สามารถเปลี่ยนแปลงได้ (ดูคำสั่ง "su") 'Chacl' เป็นชื่อพ้องของ 'aclchg' โหมดผู้ใช้หลายคนเท่านั้น


ในขณะที่ใช้งานได้จะทำให้screenทุกครั้งที่มีการแนบหน้าจอซึ่งดูเหมือนจะแตกต่างจากที่ OP ถาม
Stéphane Chazelas

1
@StephaneChazelas: ฉันไม่เห็นสิ่งบ่งชี้ใด ๆ ในคำถามที่ว่า OP มีความกังวลเกี่ยวกับความสามารถเขียนได้ในอินสแตนซ์อื่นของเซสชันที่แนบทวีคูณ นอกจากนี้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

วิธีการแก้ปัญหาปัจจุบันของฉันไปนี้คือการตั้งค่าดู Terminal เพื่ออ่านได้อย่างเดียว

บางทีมันชัดเจนเกินไป อย่างไรก็ตามคำถามไม่ต้องการวิธีแก้ไขscreenตัวเอง


1
ดูดีสำหรับฉันด้วยเทอร์มินัลอีมูเลเตอร์ที่รองรับโหมดอ่านอย่างเดียว น่าเสียดายที่เทอร์มินัลจำนวนมากไม่ได้ (เทอร์มินอล gnome / kde ไม่มี iirc) แต่บางอันก็ทำ (เช่นเทอร์มินัล
xfce4

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 ();
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.