[英]Directing external command errors to a file via ssh in perl
這實際上對我有用,但突然間它停止工作。 現在在這里卡了一個小時,但仍然不知道為什么。
我有
system("ssh -t machine command > stdout.log 2> error.log &")
總是收到一個錯誤,說Pseudo-terminal will not be allocated because stdin is not a terminal
===更新===
我已經嘗試過-T
(這根本不會返回任何錯誤)和-t -t
而不是-t
並且不會在 error.log 中直接錯誤
===更多更新===
-t -t
和-tt
給了我錯誤“tcgetattr:設備 serverCmd 的 ioctl 不合適 = 'ssh -x -n 機器',我想要的程序根本沒有啟動。刪除&
或使用qx
會給我同樣的錯誤Pseudo-terminal will not be allocated because stdin is not a terminal
只要我有-t
Pseudo-terminal will not be allocated because stdin is not a terminal
短使用 fork+exec(推薦),或使用管道打開,或 drop -t
偽終端
這里發生了很多事情。 您啟動ssh
,它需要處理(偽)終端業務,處理流 - 以及后台進程。 正是這最后一點使它變得棘手。 我的行為和你一樣。
以下是三個對我有用的解決方案/變通方法。 我推薦第一個。
命令中&
的要點是您的腳本可以立即獲得控制權。 我們可以在腳本中很好地實現這一點。 這要干凈得多,並且不依賴於系統詳細信息。 所以刪除&
並將(ssh)進程放在后台。
use warnings;
use strict;
my $cmd = 'ssh -t machine command >stdout.log 2>error.log';
my $pid = fork // die "Can't fork: $!";
if ($pid == 0) { # child
exec($cmd);
die "exec shouldn't have returned: $! ";
}
# Parent. Child became $cmd, which went its own way, never to return.
# Rest of your code, executed right away ...
error.log
可能包含Connection to machine closed.
這一行Connection to machine closed.
(它對我有用)。 如果需要,最后是對 fork+exec 的基本解釋。
以下是可能有問題且可能無法在所有地方工作的解決方法,但它們實現了我的測試所需的功能。
如果command
不需要控制 tty drop -t
。 重定向和&
仍然對我有用。
通過使用管道打開啟動 (ssh) 進程來解決STDIN
問題
my $cmd = 'ssh -t machine command >stdout.log 2>error.log &'; my $pid = open my $fh, '|-', $cmd // die "Can't fork: $!; # your other code ... close $fh;
這會“打開”(分叉)一個執行$cmd
的進程,以便$fh
是它的STDIN
,如果需要,我們的腳本可以為其提供輸入。 所以我們提供了STDIN
,ssh的偽終端沒有問題。 如果命令不需要輸入,您可以忽略它,其余的根據需要工作。
這是一個非常干凈的方法來分叉另一個進程和管道到/從它的STDIN
或STDOUT
,請參閱教程perlopentut ,參考open以及更多詳細信息安全管道打開 perlipc 。 但是,在這種情況下,我寧願使用上面的 fork+exec。
在這種情況下fork
的基本注意事項
fork創建一個新進程並將其 ID 返回給父進程,將 0 返回給子進程。 (這是唯一一次返回兩次的調用。)這個新進程是父進程的克隆,除了該進程的$pid
為零,而對於父進程,它是一個(大)整數。 (還有一些其他小得多的差異。)
所以孩子確實進入了下一個if ($pid == 0) { }
塊,而父母沒有。 這樣我們就可以將孩子和父母分開,這樣每個人都可以運行專用於他們的代碼。 我們得到並行執行(原則上,也主要是在實踐中)。
在if
塊中,子進程被exec執行的程序完全替換,在本例中由您的ssh
命令替換。 exec
根本不會返回(除非調用本身失敗)。 父級繼續在if
之后運行,正常執行那里的任何代碼而不會阻塞。
這樣我們就可以分離出另一個程序,而您的程序可以繼續其業務,而無需等待另一個程序完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.