Chciałbym móc sprawdzać postęp i wyniki moich istniejących screen
sesji, ale tylko w trybie do odczytu, aby zapobiec wystąpieniu błędu z powodu błędu użytkownika. Czy jest na to sposób?
Chciałbym móc sprawdzać postęp i wyniki moich istniejących screen
sesji, ale tylko w trybie do odczytu, aby zapobiec wystąpieniu błędu z powodu błędu użytkownika. Czy jest na to sposób?
Odpowiedzi:
Niestety myślę, że odpowiedź brzmi „nie”. Pytający tego pytania przestawił się na tmux, ponieważ ma tę funkcję (przekazujesz -r
flagę podczas dołączania), więc jeśli masz opcję przełączania multiplekserów, to prawdopodobnie najlepszy wybór
Możesz spróbować:
aclchg username -w "#"
jeśli działasz screen
w trybie wielu użytkowników (ale nie musiałem robić nic specjalnego, aby działał podczas testowania go jako pojedynczy dołączony użytkownik). Jeśli musisz przejść do trybu wielu użytkowników, użyj multiuser on
.
Możesz użyć *
nazwy użytkownika, aby wpłynąć na wszystkich użytkowników.
Używanie +w
zamiast -w
włącza tryb zapisu.
Od man screen
:
aclchg lista
nazw użytkowników lista uprawnień chacl lista nazw użytkownikówZmień uprawnienia dla listy użytkowników oddzielonych przecinkami. Bity uprawnień są reprezentowane jako „r”, „w” i „x”. Prefiks „+” przyznaje uprawnienie, „-” usuwa je. Trzeci parametr to rozdzielona przecinkami lista poleceń i / lub okien (określona liczbą lub tytułem). Specjalna lista „#” odnosi się do wszystkich okien, „?” do wszystkich poleceń. jeśli nazwy użytkowników składają się z jednego „*”, dotyczy to wszystkich znanych użytkowników. Polecenie można wykonać, gdy użytkownik ma do niego bit „x”. Użytkownik może wpisać dane wejściowe do okna, gdy ma ustawiony bit „w” i żaden inny użytkownik nie uzyska blokady zapisu dla tego okna. Inne bity są obecnie ignorowane. Aby wycofać writelock od innego użytkownika w oknie 2: „aclchg nazwa użytkownika -w + w 2”. Aby zezwolić na dostęp tylko do odczytu do sesji: 'aclchg nazwa użytkownika -w "#"'. Gdy tylko nazwa użytkownika będzie znana z ekranu, może dołączyć do sesji i (domyślnie) ma pełne uprawnienia do wszystkich poleceń i okien. Zezwolenie na wykonywanie poleceń acl, `at 'i innych również powinno zostać usunięte lub użytkownik może odzyskać uprawnienia do zapisu. Praw do specjalnej nazwy użytkownika nikt nie może zostać zmieniony (patrz polecenie „su”). „Chacl” jest synonimem „aclchg”. Tylko tryb wielu użytkowników. a inne również powinny zostać usunięte lub użytkownik może odzyskać uprawnienia do zapisu. Praw do specjalnej nazwy użytkownika nikt nie może zostać zmieniony (patrz polecenie „su”). „Chacl” jest synonimem „aclchg”. Tylko tryb wielu użytkowników. a inne również powinny zostać usunięte lub użytkownik może odzyskać uprawnienia do zapisu. Praw do specjalnej nazwy użytkownika nikt nie może zostać zmieniony (patrz polecenie „su”). „Chacl” jest synonimem „aclchg”. Tylko tryb wielu użytkowników.
aclcng
polecenie może określać konkretnych użytkowników, określone polecenia i / lub określone okna, więc jest to dość drobna ziarnistość. Więc to nie jest „wszędzie”.
Znalazłem dość proste obejście, które pozwala bezpiecznie monitorować wyjście.
Uruchom następujące polecenia natychmiast po wejściu do sesji ekranowej:
echo /tmp/$STY
touch /tmp/$STY
chmod 0600 /tmp/$STY
script -a -f /tmp/$STY
Odłącz sesję Ctrl-A di śledź dane wyjściowe skryptu, np .:
tail -f /tmp/10751.test
Moje obecne rozwiązanie tego problemu polega na ustawieniu widoku terminala na Tylko do odczytu .
Może to zbyt oczywiste. Pytanie nie wymagało jednak rozwiązania screen
.
napisałem skrypt php o nazwie readscreen
... dołączający do sesji ekranowych w trybie tylko do odczytu. zapisz go /usr/bin/readscreen
i uruchom chmod 0555 /usr/bin/readscreen
, i upewnij się, że masz zainstalowane php-cli z rozszerzeniem php-pcntl, a readscreen
następnie możesz napisać, a następnie dowolne polecenie, którego użyjesz do połączenia z normalnym ekranem, na przykład:
readscreen -S foo -x
i będziesz połączony z sesją foo w trybie tylko do odczytu . zwróć uwagę, że nie jest to dokładnie testowane, ale wydaje się działać dobrze. kod źródłowy ekranu odczytu:
#!/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 ();
}
screen
tylko do odczytu jest dołączana wszędzie sesja ekranowa, która wygląda inaczej niż to, o co poprosił OP.