When I terminate a dying Perl test run using prove -v , why are results not saved to a text file via STDOUT? - perl

I'm driving SeleniumRC and a page hangs, so I hit Ctrl-C to stop testing and address the issue. If I pass a txt file via the command line like so:
prove -v some.t :: data.csv > testresults.txt
...I either get nothing or "Terminate batch job (Y/N)? " in the text file. Note that if I don't pass a file for output via the command line the results scroll by as expected.
Does prove have an option to write to a file via stdout that isn't -v?
This issue persists when I add $| = 1; in any of its forms to either prove.pm or some.t. Is there something in prove or Test::Harness that is overriding my autoflush setting?
I've also tried this variation:
prove -v some.t > testresults.txt :: data.csv

Sounds like you are suffering from buffering. The output is buffered (when not sent to a terminal), and those buffers aren't flushed when you fill the application with Ctrl-C.
If the output comes from a Perl script, try adding $| = 1; to it.

Related

Cannot redirect EXE output to file

I have an exe program I'm running on Windows 10 using PowerShell. When I run it, I get the following output.
> .\Program.exe
Unlocked level 7/10
When trying to redirect all output or just stdout to a file, the program stops giving output. For example
PS > .\Program.exe > .\out.txt
PS > cat .\out.txt
PS >
I did not write the program but what I know is that it was written in C++.
Is there any trick to get the output into a file? I tried running in python and writing output to a file, running in python without fetching the output and redirecting, running from another powershell, and lots of other combinations but they don't seem to be working. Also, when running from Git Bash, I get no output at all.
I was thinking about some checks on the descriptors but I'm not sure since I don't have the source code, only the asm code
It looks like Program.exe is actually generating an error, and not output, first commenter is trying to get you to see that, but not really explaining that part...
(NOTE: You aren't actually using any powershell besides an implied "Invoke-Expression")I think you might be dealing with STDERR vs. STDOUT, when I invoke reg.exe in that fashion from powershell I get no output to the text file. This is because the text I was seeing was an error message ( Contents of STDERR ) from reg.exe, not the output ( contents of STDOUT ) from the command. When I passed proper parameters to it ( reg query HKLM\Software\Microsoft > C:\Users\foo\Documents\foo.txt) it wrote the Contents of STDOUT to the text file instead of the screen.
Here is an article that explains it better than I just did:
https://support.microsoft.com/en-us/help/110930/redirecting-error-messages-from-command-prompt-stderr-stdout

can't find perl error log

I have a perl file (eg:test.pl) which does some DB operations.
While testing, its working fine.
I execute this file as a background process by using the command
perl test.pl &
Its working properly for some days.
But after some days ,the file execution get stopped.
How can I find the reason or view the error?
I checked the log file "/var/log/httpd/error_log", but can't find anything.
I keep the perl file in a server, which runs in Cent OS.
Any one have idea?
There is no 'perl error log'
But you can define a destination for output to be saved to, just run your script like this:
perl test.pl >> /var/log/some-log-file.log 2>&1 &
This will redirect STDOUT (normal shell output) and STDERR (error output) to /var/log/some-log-file.log instead of to the terminal.
You may also wish to use nohup in order to have the script ignore HANGUP (logout) signals, which could be causing your unexpected terminations:
nohup perl test.pl >> /var/log/some-log-file.log 2>&1 &
Obviously, whichever user you run the script as will need to have write access to the log file.

Odd behavior with Perl system() command

Note that I'm aware that this is probably not the best or most optimal way to do this but I've run into this somewhere before and I'm curious as to the answer.
I have a perl script that is called from an init that runs and occasionally dies. To quickly debug this, I put together a quick wrapper perl script that basically consists of
#$path set from library call.
while(1){
system("$path/command.pl " . join(" ",#ARGV) . " >>/var/log/outlog 2>&1");
sleep 30; #Added this one later. See below...
}
Fire this up from the command line and it runs fine and as expected. command.pl is called and the script basically halts there until the child process dies then goes around again.
However, when called from a start script (actually via start-stop-daemon), the system command returns immediately, leaving command.pl running. Then it goes around for another go. And again and again. (This was not fun without the sleep command.). ps reveals the parent of (the many) command.pl to be 1 rather than the id of the wrapper script (which it is when I run from the command line).
Anyone know what's occurring?
Maybe the command.pl is not being run successfully. Maybe the file doesn't have execute permission (do you need to say perl command.pl?). Maybe you are running the command from a different directory than you thought, and the command.pl file isn't found.
There are at least three things you can check:
standard error output of your command. For now you are swallowing it by saying 2>&1. Remove that part and observe what errors the system command produces.
the return value of system. The command may run and system may still return an exit code, but if system returns 0, you know the command was successful.
Perl's error variable $!. If there was a problem, Perl will set $!, which may or may not be helpful.
To summarize, try:
my $ec = system("command.pl >> /var/log/outlog");
if ($ec != 0) {
warn "exit code was $ec, \$! is $!";
}
Update: if multiple instance of the command keep showing up in your ps output, then it sounds like the program is forking and running itself in the background. If that is indeed what the command is supposed to do, then what you do NOT want to do is run this command in an endless loop.
Perhaps when run from a deamon the "system" command is using a different shell than the one used when you are running as yourself. Maybe the shell used by the daemon does not recognize the >& construct.
Instead of system("..."), try exec("...") function if that works for you.

Redirecting a .bat-file-containing-executable's stdout to a file

I have a batch file that calls an executable program. The program (compiled C code) generates some output to stdout. The batch echos some output as well. When running the bat, I use redirection (>) to get the text to a file.
mybat.bat contains:
myprog.exe arg1 %1 arg3
echo Done
then, at the console:
C:\> mybat arg2 > log.txt
The problem is that in log.txt I get only the output of the echo Done command and not the output of myprog.exe. Without the redirection, I get the expected output on the screen.
Note: Under Windows XP
Update: this gets even weirder. When running myprog.exe from the command prompt, I get the expected output to the console. Then, when redirecting its output to log.txt, the file is empty! The printing is done using fprintf(stdout, "...") or fprintf(ofp, "...") where ofp is assigned: FILE *ofp = stdout;.
Further investigation: it seems like the fprintf(stdout... lines where redirected, while the fprintf(ofp... are not (yes, the pointer is assigned correctly). I also found that the program crashes at somepoint (at a call to feof()). So, my conclusion is that due to the abnormal termination of the program, the standard output buffers were not written to the file. HOWEVER - this happened only for the lines that use the pointer. I guess that these lines have shorter output, so the flush frequency is lower (I used the stdout line to print a deliberate help message).
Once solving the crash problem, the data is now redirected to the log file. Thanks for your help.
Try redirecting both stdout and stderr to the log file.
mybat arg2 1>&2> log.txt
Try this:
cmd /c "mybat.bat arg2" > log.txt

STDOUT redirected externally and no output seen at the console

I have a program which reads the output from external application.The external app gives set of output. My program reads the output from this external app while($line=<handle to external app>) and print it to STDOUT.But the "print $line STDOUT" prints only some lines and when the error has occurred ,print to STDOUT is not working , but my one more logging statement "push #arr,$line" has stored complete output from the external app.From this i got to know STDOUT is not working properly when error happens.
Eg:
if external app output is like:
Starting command
First command executed successfully
Error:123 :next command failed
Program terminated
In here the STDOUT prints only :
Starting command
First command executed successfully
But if I check the array it has complete output including error details. So I guessed STDOUT has been redirected or lost.
So I tried storing STDOUT in the beginning of the program to $old_handle using open and then try to restore it before print statement using select($old_handle) (thinking some thing redirects STDOUT when error happens)
But I was not successfull, I don't know what is wrong here. Please help me.
It's possible the output is being buffered. Try setting
$| = 1;
at the start of your program. This will cause the output to be displayed straight away, rather than being buffered for later.
Just guess, may be because error output doesn't go to STDOUT. Use redirect
first_program |& perl_program
or
first_program 2>&1 | perl_program