Tôi muốn có thể kiểm tra tiến trình và đầu ra của các screen
phiên hiện tại của mình , nhưng theo cách chỉ đọc, để ngăn chặn sự cố xảy ra do lỗi người dùng. Có cách nào để làm việc này không?
Tôi muốn có thể kiểm tra tiến trình và đầu ra của các screen
phiên hiện tại của mình , nhưng theo cách chỉ đọc, để ngăn chặn sự cố xảy ra do lỗi người dùng. Có cách nào để làm việc này không?
Câu trả lời:
Thật không may, tôi nghĩ rằng câu trả lời là không. Người hỏi của câu hỏi này chuyển sang tmux cụ thể vì nó có tính năng đó (bạn chuyển -r
cờ khi đính kèm), vì vậy nếu bạn có tùy chọn chuyển đổi bộ ghép kênh thì đó có lẽ là lựa chọn tốt nhất của bạn
Bạn co thể thử:
aclchg username -w "#"
nếu bạn chạy screen
ở chế độ nhiều người dùng (nhưng tôi không phải làm gì đặc biệt để làm cho nó hoạt động khi kiểm tra nó như một người dùng đính kèm). Nếu bạn cần phải vào chế độ nhiều người dùng, hãy sử dụng multiuser on
.
Bạn có thể sử dụng *
tên người dùng để ảnh hưởng đến tất cả người dùng.
Sử dụng +w
thay vì -w
cho phép chế độ ghi.
Từ man screen
:
aclchg tên người dùng permbits danh sách
chacl tên người dùng permbits danh sáchThay đổi quyền cho danh sách người dùng được phân tách bằng dấu phẩy. Các bit cho phép được biểu diễn dưới dạng 'r', 'w' và 'x'. Tiền tố '+' cấp quyền, '-' xóa nó. Tham số thứ ba là danh sách các lệnh và / hoặc cửa sổ được phân tách bằng dấu phẩy (được chỉ định theo số hoặc tiêu đề). Danh sách đặc biệt '#' đề cập đến tất cả các cửa sổ, '?' cho tất cả các lệnh. nếu tên người dùng bao gồm một '*', tất cả người dùng đã biết sẽ bị ảnh hưởng. Một lệnh có thể được thực thi khi người dùng có bit 'x' cho nó. Người dùng có thể nhập dữ liệu vào một cửa sổ khi anh ta đã thiết lập bit 'w' và không người dùng nào khác nhận được một danh sách cho cửa sổ này. Các bit khác hiện đang bị bỏ qua. Để rút danh sách ghi từ người dùng khác trong cửa sổ 2: 'tên người dùng aclchg -w + w 2'. Để cho phép truy cập chỉ đọc vào phiên: 'aclchg tên người dùng -w "#"'. Ngay khi biết tên người dùng được sàng lọc, anh ta có thể đính kèm vào phiên và (theo mặc định) có toàn quyền cho tất cả các lệnh và cửa sổ. Quyền thực thi cho các lệnh acl, 'at' và các lệnh khác cũng sẽ bị xóa hoặc người dùng có thể lấy lại quyền ghi. Quyền của tên người dùng đặc biệt không ai có thể thay đổi (xem lệnh "su"). 'Chacl' là từ đồng nghĩa với 'aclchg'. Chỉ có nhiều chế độ người dùng. và những người khác cũng nên được gỡ bỏ hoặc người dùng có thể lấy lại quyền ghi. Quyền của tên người dùng đặc biệt không ai có thể thay đổi (xem lệnh "su"). 'Chacl' là từ đồng nghĩa với 'aclchg'. Chỉ có nhiều chế độ người dùng. và những người khác cũng nên được gỡ bỏ hoặc người dùng có thể lấy lại quyền ghi. Quyền của tên người dùng đặc biệt không ai có thể thay đổi (xem lệnh "su"). 'Chacl' là từ đồng nghĩa với 'aclchg'. Chỉ có nhiều chế độ người dùng.
aclcng
lệnh có thể chỉ định người dùng cụ thể, các lệnh cụ thể và / hoặc các cửa sổ cụ thể để mức độ chi tiết khá tốt. Vì vậy, đó không phải là "ở khắp mọi nơi".
Tôi đã tìm thấy một công việc khá đơn giản cho phép người ta theo dõi đầu ra một cách an toàn.
Chạy các lệnh sau ngay sau khi vào phiên màn hình:
echo /tmp/$STY
touch /tmp/$STY
chmod 0600 /tmp/$STY
script -a -f /tmp/$STY
Tách phiên với Ctrl-A dvà làm theo đầu ra tập lệnh, ví dụ:
tail -f /tmp/10751.test
Giải pháp hiện tại của tôi cho vấn đề này là đặt Terminal View thành ReadOnly .
Có lẽ nó quá rõ ràng. Tuy nhiên, câu hỏi không yêu cầu một giải pháp screen
.
tôi đã viết một tập lệnh php được gọi là readscreen
... đính kèm vào các phiên màn hình ở chế độ chỉ đọc. lưu nó vào /usr/bin/readscreen
và chạy chmod 0555 /usr/bin/readscreen
, và đảm bảo cài đặt php-cli với phần mở rộng php-pcntl và bạn có thể viết readscreen
theo bất kỳ lệnh nào bạn sử dụng để kết nối với màn hình bình thường, ví dụ:
readscreen -S foo -x
và bạn sẽ được kết nối với phiên foo theo cách chỉ đọc . lưu ý rằng nó không được thử nghiệm rộng rãi, nhưng dường như hoạt động tốt. mã nguồn màn hình đọc:
#!/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
chỉ đọc ở mọi nơi mà phiên màn hình được đính kèm trông giống như những gì OP yêu cầu.