読み取り専用モードで「画面」を実行する方法はありますか?


16

既存のscreenセッションの進行状況と出力を確認できるようにしたいのですが、ユーザーエラーが原因で問題が発生するのを防ぐために、読み取り専用の方法で確認したいと思います。これを行う方法はありますか?

回答:


8

残念ながら、答えはノーだと思います。アスカーこの質問はに切り替えtmuxは、それがその機能(あなたが合格持っているので、特に-rあなたがマルチプレクサを切り替えるためのオプションを持っている場合、それはおそらくあなたの最良の選択ですが、取り付け時にフラグ)


3

あなたが試すことができます:

aclchg username -w "#"

screenマルチユーザーモードで実行する場合(ただし、単一の接続ユーザーとしてテストする場合、特別な操作を行う必要はありませんでした)。マルチユーザーモードに入る必要がある場合は、を使用しますmultiuser on

*ユーザー名に使用して、すべてのユーザーに影響を与えることができます。

+w代わりにを使用すると-w、書き込みモードが有効になります。

からman screen

aclchgユーザー名permbitsリスト
chaclユーザー名permbitsリスト

ユーザーのコンマ区切りリストのアクセス許可を変更します。許可ビットは、「r」、「w」、および「x」として表されます。接頭辞「+」は許可を付与し、「-」はそれを削除します。3番目のパラメーターは、コマンドまたはウィンドウ(あるいはその両方)のコンマ区切りリストです(番号またはタイトルで指定)。特別なリスト「#」はすべてのウィンドウを指し、「?」すべてのコマンドに。ユーザー名が単一の「*」で構成される場合、すべての既知のユーザーが影響を受けます。ユーザーが「x」ビットを持っている場合、コマンドを実行できます。ユーザーは、 'w'ビットが設定されていて、他のユーザーがこのウィンドウの書き込みロックを取得していない場合、ウィンドウに入力を入力できます。他のビットは現在無視されます。ウィンドウ2の別のユーザーから書き込みロックを撤回するには: 'aclchg username -w + w 2'。セッションへの読み取り専用アクセスを許可するには: 'aclchg username -w "#"'。ユーザーの名前がスクリーンで認識されるとすぐに、ユーザーはセッションにアタッチでき、(デフォルトで)すべてのコマンドとウィンドウに対する完全な権限を持ちます。aclコマンド、「at」などの実行許可も削除する必要があります。そうしないと、ユーザーが書き込み許可を取り戻すことができます。特別なユーザー名nobodyの権限は変更できません(「su」コマンドを参照)。「Chacl」は「aclchg」の同義語です。マルチユーザーモードのみ。その他も削除する必要があります。削除しないと、ユーザーは書き込み権限を取り戻すことができます。特別なユーザー名nobodyの権限は変更できません(「su」コマンドを参照)。「Chacl」は「aclchg」の同義語です。マルチユーザーモードのみ。その他も削除する必要があります。削除しないと、ユーザーは書き込み権限を取り戻すことができます。特別なユーザー名nobodyの権限は変更できません(「su」コマンドを参照)。「Chacl」は「aclchg」の同義語です。マルチユーザーモードのみ。


これは機能しscreenますが、画面セッションが接続されているすべての場所で読み取り専用になり、OPが要求したものとは異なります。
ステファンChazelas

1
@StephaneChazelas:多重接続セッションの他のインスタンスでの書き込み可能性についてOPが懸念しているという質問には、何も示されていません。また、aclcngコマンドは特定のユーザー、特定のコマンド、特定のウィンドウを指定できるため、かなり細かく指定できます。したがって、それは「どこでも」ではありません。
追って通知があるまで一時停止します。

3

出力を安全に監視できる、かなり簡単な回避策を見つけました。

screenセッションに入った直後に次のコマンドを実行します。

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

readscreen読み取り専用モードでスクリーンセッションにアタッチするというPHPスクリプトを記述しました。に保存して/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.