从Python运行Perl脚本并将输出写入文件时,为什么文件是空的?
我有以下Perl脚本,它以以太网接口名称和传输速率作为参数:从Python运行Perl脚本并将输出写入文件时,为什么文件是空的?,python,linux,perl,Python,Linux,Perl,我有以下Perl脚本,它以以太网接口名称和传输速率作为参数: #!/usr/bin/perl -w $prevRXpacks = 0; $prevTXpacks = 0; $prevRXbytes = 0; $prevTXbytes = 0; $recentRXpacks = 0; $recentTXpacks = 0; $recentRXbytes = 0; $recentTXbytes = 0; $time_wait_default = 2; $time_run_default = 0;
#!/usr/bin/perl -w
$prevRXpacks = 0;
$prevTXpacks = 0;
$prevRXbytes = 0;
$prevTXbytes = 0;
$recentRXpacks = 0;
$recentTXpacks = 0;
$recentRXbytes = 0;
$recentTXbytes = 0;
$time_wait_default = 2;
$time_run_default = 0;
$prev = 0;
$overflow = 4 * 1024 * 1024 * 1024;
$k = 1000;
$m = $k * $k;
$format = "";
$format_value = 1;
$hdr_format = "Bytes/s";
if ( defined ($ARGV[0]) && ($ARGV[0] eq "--help") ) {
print "Usage: $0 <device> [-r runtime] [-d delaytime]\n";
print " -r time to run traffic monitor in seconds (default = 0 <- forever)\n";
print " -d delay between two records in seconds (default = $time_wait_default)\n";
print " -k, -K print transfer rate in kbits/s or KBytes/s\n";
print " -m, -M print transfer rate in mbits/s or MBytes/s\n";
die "\n";
}
open (OUT, "/dev/null");
select (OUT);
if ( !defined($ARGV[0]) || !`/sbin/ifconfig $ARGV[0]` ) {
close (OUT);
select (STDOUT);
die "Usage $0 <device> [-r runtime] [-d delaytime] [-kmKM].\nTry --help for more.\n";
}
close (OUT);
select (STDOUT);
$time_wait = $time_wait_default;
$time_run = $time_run_default;
$i = 1;
while ( defined ($ARGV[$i]) ) {
if ($ARGV[$i] eq "-d") {
$time_wait = $ARGV[++$i] || $time_wait_default;
}
if ($ARGV[$i] eq "-r") {
$time_run = $ARGV[++$i] || $time_run_default;
}
if ($ARGV[$i] eq "-K") {
$format = $hdr_format = "KBytes/s";
$format_value = $k;
}
if ($ARGV[$i] eq "-k") {
$format = $hdr_format = "Kbits/s";
$format_value = $k/8;
}
if ($ARGV[$i] eq "-M") {
$format = $hdr_format = "MBytes/s";
$format_value = $m;
}
if ($ARGV[$i] eq "-m") {
$format = $hdr_format = "Mbits/s";
$format_value = $m/8;
}
$i++;
}
print "Traffic monitoring...\n";
# main loop
$time_loop = $time_run + time();
while ( time() < $time_loop || !$time_run ) {
$recent = time();
foreach $_ (`/sbin/ifconfig $ARGV[0]`) {
if (/RX.*packets/) {
($blabla1, $blabla2, $blabla3) = split(/\s+/);
($blabla1, $recentRXpacks, $blabla2) = split(/:/, $blabla3);
}
if (/TX.*packets/) {
($blabla1, $blabla2, $blabla3) = split(/\s+/);
($blabla1, $recentTXpacks, $blabla2) = split(/:/, $blabla3);
}
if (/RX.*bytes/) {
($blabla1, $blabla2, $blabla3) = split(/:/);
($recentRXbytes) = split(/ /, $blabla2);
($recentTXbytes) = split(/ /, $blabla3);
}
}
if ( ($recent > $prev) && $prev) {
$interval = $recent - $prev;
# $interval = $time_wait;
$RXpacks = round (rate ($prevRXpacks, $recentRXpacks, $interval));
$TXpacks = round (rate ($prevTXpacks, $recentTXpacks, $interval));
$RXbytes = round (rate ($prevRXbytes, $recentRXbytes, $interval)/$format_value);
$TXbytes = round (rate ($prevTXbytes, $recentTXbytes, $interval)/$format_value);
write;
}
$prev = $recent;
$prevRXpacks = $recentRXpacks;
$prevTXpacks = $recentTXpacks;
$prevRXbytes = $recentRXbytes;
$prevTXbytes = $recentTXbytes;
$time_delay = $time_wait + time();
while (time() < $time_delay) {}
}
format STDOUT_TOP =
RX [packets/s] TX [packets/s] RX [@<<<<<<<] TX [@<<<<<<<]
$hdr_format, $hdr_format
.
format STDOUT =
@<<<<<<<<<<<<<< @<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<
$RXpacks, $TXpacks, $RXbytes." ".$format, $TXbytes." ".$format
.
sub rate {
my ($prev, $recent);
($prev, $recent, $interval) = @_;
if (($recent = $recent - $prev) <0) {
$recent += $overflow;
}
return $recent/$interval;
}
sub round {
my ($mod, $result);
$result = int ($_[0]);
$mod = ($_[0] - $result) ;
if ( $mod >= 0.5) {
$result++;
}
return $result;
}
文件已创建,但为空。如何解决此问题?请参考我认为在调用POpen
时需要显式指定stderr=subprocess.PIPE的文档,否则子流程stderr将连接到主程序stderr
试试这个:
proc=subprocess.Popen(command, stderr=subprocess.PIPE)
测试:
编辑:您的perl进程实际上是写入到stderr还是stdout?您可以将文件描述符传递到Popen
,程序将直接写入文件,而无需读取管道。我有点困惑,因为您试图读取的是stderr
而不是stdout
,所以编写了一个将两个管道写入一个文件的示例
#!/usr/bin/python
import sys
import subprocess
import datetime
import os
import time
command = ["perl","/root/Desktop/myethtraffic.pl", "eth0", "M"]
dir_name = "/root/Desktop/"
logfile = open("/root/Desktop/aa1a.txt", 'w')
proc=subprocess.Popen(command,
stdout=open("/root/Desktop/aa1a.txt", 'w'),
stderr=subprocess.STDOUT)
proc.wait()
有可能perl
不在您的路径中。
将完整路径传递给perl
,而不是字符串“perl”,例如
另一个选项是使用shell运行命令,以模拟直接从命令行执行命令时的运行方式
subprocess.Popen("/root/Desktop/myethtraffic.pl eth0 M", ..., shell=True)
它是从命令行工作的吗?是的,如果是这样的话。/myethtraffic eth0 M它与stdout=subprocess.pipe
一起工作,然后读取proc.stdout
?我尝试了我们的解决方案,但问题是如果我将ctrl+c发送到我的python脚本,但它没有停止,我的意思是perl脚本继续运行,那么我必须通过找到perl的pid来终止它在linux中使用“top”命令并将pid赋予“kill”命令,您可以通过捕获SIGHUP
并退出来在子perl脚本中修复任何建议。在python父级中,您可以创建一个全局列表,其中包含要终止的进程。在程序运行时添加/删除Popens,并实现一个atexit
钩子,该钩子杀死列表中的任何内容。执行perl命令时,问题是将结果获取到文件中。
#!/usr/bin/python
import sys
import subprocess
import datetime
import os
import time
command = ["perl","/root/Desktop/myethtraffic.pl", "eth0", "M"]
dir_name = "/root/Desktop/"
logfile = open("/root/Desktop/aa1a.txt", 'w')
proc=subprocess.Popen(command,
stdout=open("/root/Desktop/aa1a.txt", 'w'),
stderr=subprocess.STDOUT)
proc.wait()
command = ["/usr/bin/perl", ...]
subprocess.Popen("/root/Desktop/myethtraffic.pl eth0 M", ..., shell=True)