기존 screen
세션 의 진행 상황과 출력을 확인 하지만 읽기 전용 방식으로 사용자 오류로 인해 무언가 잘못되는 것을 방지하고 싶습니다 . 이것을 할 수있는 방법이 있습니까?
답변
불행히도 대답은 ‘아니오’라고 생각합니다. 의 아스 커 이 문제는 로 전환 TMUX 가 그 기능을 (당신이 통과 있기 때문에 특별히 -r
당신이 멀티플렉서를 전환 할 수있는 옵션이있는 경우에 그래서 아마 당신의 최선의 선택이다, 부착 할 때 플래그)
답변
당신은 시도 할 수 있습니다:
aclchg username -w "#"
screen
다중 사용자 모드에서 실행하는 경우 (단 하나의 연결된 사용자로 테스트 할 때 특별한 작업을 수행 할 필요가 없습니다). 다중 사용자 모드로 들어가야하는 경우을 사용하십시오 multiuser on
.
당신이 사용할 수있는 *
모든 사용자에게 영향을하기 위해 사용자 이름.
사용은 +w
대신 -w
쓰기 모드를 가능하게한다.
보낸 사람 man screen
:
aclchg 사용자 이름 permbits 목록
chacl 사용자 이름 permbits 목록쉼표로 구분 된 사용자 목록에 대한 권한을 변경하십시오. 권한 비트는 ‘r’, ‘w’및 ‘x’로 표시됩니다. 접두사 ‘+’는 권한을 부여하고 ‘-‘는 권한을 제거합니다. 세 번째 매개 변수는 쉼표로 구분 된 명령 및 / 또는 창 목록 (번호 또는 제목으로 지정)입니다. 특수 목록 ‘#’은 모든 창 ‘?’을 나타냅니다. 모든 명령에. 사용자 이름이 단일 ‘*’로 구성된 경우 알려진 모든 사용자가 영향을받습니다. 사용자에게 ‘x’비트가 있으면 명령을 실행할 수 있습니다. 사용자는 ‘w’비트가 설정되어 있고 다른 사용자가이 창에 대한 쓰기 잠금을 얻지 못할 때 창에 입력을 입력 할 수 있습니다. 다른 비트는 현재 무시됩니다. 창 2에서 다른 사용자로부터 쓰기 잠금을 해제하려면 : ‘aclchg username -w + w 2’. 세션에 대한 읽기 전용 액세스를 허용하려면 ‘aclchg username -w “#”‘. 사용자 이름이 화면에 표시되는 즉시 세션에 연결할 수 있으며 기본적으로 모든 명령과 창에 대한 모든 권한을 갖습니다. acl 명령,`at ‘및 기타 명령에 대한 실행 권한도 제거해야합니다. 그렇지 않으면 사용자가 쓰기 권한을 다시 얻을 수 있습니다. 특별한 사용자 이름의 권리는 누구도 변경할 수 없습니다 ( “su”명령 참조). ‘Chacl’은 ‘aclchg’와 동의어입니다. 다중 사용자 모드 만 해당. 다른 사용자도 제거해야합니다. 그렇지 않으면 사용자가 쓰기 권한을 다시 얻을 수 있습니다. 특별한 사용자 이름의 권리는 누구도 변경할 수 없습니다 ( “su”명령 참조). ‘Chacl’은 ‘aclchg’와 동의어입니다. 다중 사용자 모드 만 해당. 다른 사용자도 제거해야합니다. 그렇지 않으면 사용자가 쓰기 권한을 다시 얻을 수 있습니다. 특별한 사용자 이름의 권리는 누구도 변경할 수 없습니다 ( “su”명령 참조). ‘Chacl’은 ‘aclchg’와 동의어입니다. 다중 사용자 모드 만 해당.
답변
출력을 안전하게 모니터링 할 수있는 상당히 간단한 해결 방법을 찾았습니다.
스크린 세션에 들어간 직후 다음 명령을 실행하십시오.
echo /tmp/$STY
touch /tmp/$STY
chmod 0600 /tmp/$STY
script -a -f /tmp/$STY
Ctrl-A d다음과 같이 세션을 분리하고 스크립트 출력을 따르십시오.
tail -f /tmp/10751.test
답변
이것에 대한 나의 현재 해결책은 터미널보기를 ReadOnly 로 설정하는 것 입니다.
어쩌면 너무 분명 할 수도 있습니다. 그러나 질문 screen
자체 에는 해결책이 필요하지 않았습니다 .
답변
readscreen
읽기 전용 모드에서 화면 세션에 연결 하는 PHP 스크립트를 작성했습니다 . 저장 /usr/bin/readscreen
하고 실행 chmod 0555 /usr/bin/readscreen
하고 php-pcntl 확장자로 php-cli를 설치했는지 확인하십시오 readscreen
. 예를 들어 다음과 같이 일반 화면에 연결하는 데 사용할 명령을 쓸 수 있습니다 .
readscreen -S foo -x
그리고 당신은 읽기 전용 방식으로 foo 세션 에 연결됩니다 . 광범위하게 테스트되지는 않았지만 정상적으로 작동하는 것 같습니다. 리드 스크린 소스 코드 :
#!/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 ();
}