Storing output of perl script to a file - perl

I"m calling a perl script stored in one PC, for example with name machine1 from say machine2 using the command:
system("perl /CC/builds/123.pl\n");
Now, i need to get the log of the whole perl file executed to be stored in a say 123.txt file and created on machine1.Can any text file be opened in the perl file at the beginning which stored only output of the line executed?
Please help.
Thanks,
Ramki

I'm quite new on that and I don't know if I am understanding your question, but why you don't use "backticks" instead of "system"? It would let you store the output in a variable and then you can do with this variable whatever you want.
About backticks: What's the difference between Perl's backticks, system, and exec?

Related

How do I make a perl script run another perl script?

I am writing a large Perl script, which needs to utilize other existing Perl scripts. The problem is the main script needs to reference many different scripts from different folders. For example the main script would be contained in:
/perl/programs/io
It may need to run a script which is stored in:
/perl/programs/tools
Note that there are other orthogonal folders besides tools so I need to be able to access any of them on the fly.
Currently this is what I got:
my $mynumber = '../tools/convert.pl bin2dec 1011';
In theory it should move back from the io directory then enter the appropriate tool directory and call the convert.pl script while passing it the parameters.
All this does is store the string in the single quotes to $myNumber.
I like to assign the output of a command to an array so I can loop through the array to find error or other messages. For example if I'm making a zip file to email to someone I want to check to see if the zip program had any errors before I continue to make and send the email.
#msgs = `zip -f myfile.zip *.pl`; # Use backticks
You can also assign the output to a scalar:
$msg = `ls -al *.pl`; # Use backticks
To run any system command or script all you have to do is use `backticks`. From observing another programer's perl code, I misread these strange quotes for 'single quotes'.
backticks are also nice because they return the text in STDOUT to your perl script so that the output can be assigned to a variable, something I have found impossible if using system("");
The similar question answer does not work with my version of perl. The line
use IPC::System::Simple qw(system capture);
throws some errors. However just using system works, like this:
my $mynumber = system($^X, "../tools/convert.pl", 'bin2dec', '1011');
I can use the above without setting equal to something to execute scripts which return no value and are only sent arguments.
This seems to be the easiest way to do what I need to and the entire programs folder can be moved anywhere and it will still work as no parent directories above programs are used.

Perl script messes with file descriptor in matlab

I use a perl script for replacing some strings in a data file. The perl script is called from within a matlab program, which writes to the data file before the execution of the perl script and after it's execution.
My matlab program would then write to the data file, but for some reason it does not.
Here is a minimal example:
Matlab code:
f = fopen('output.txt','a');
fprintf(f,'This is written\n');
perl('replace.perl','output.txt');
fprintf(f,'This is not\n');
[fname perm] = fopen(f)
type('output.txt');
fclose(f);
perl script:
#!/usr/bin/perl -i
while(<>){
s/This/This here/;
print;
}
close;
The variables fname and perm are correctly assigned. The output of type is only "This here is written".
I am quite new to perl and so I probably make some rookie mistake in the script that I can't find.
Thanks for helping.
The secret is in the -i. In-place editing in perl, and in many other programs, is accomplished by opening the original file for reading, opening a temp file for writing, then unlinking the original file and renaming the temp file to the original file's name.
Now after running your perl script, poor matlab is left holding a file handle to a now unlinked file. You continue writing, but there's no easy way to see what was written... Even if the file had not changed out from under matlab, you would have had to deal with the fact that matlab was about to write to a spot that would now no longer be the end of the file.
In the end, you need to be very careful of having two programs/users/computers writing to the same file at the same time. Close the matlab file handle before calling perl. Reopen it for appending later if that proves to be really necessary.

Pass variable from perl script to shell script in Unix

Am pretty much aware of passing variables between shell scripts using 'EXPORT' command. But am stuck with passing a variable value from a perl script to shell script in UNIX operating systems.
Let me explain it clearly.
I have a parent shell called parent_shell.sh. Inside this shell script am using a variable called 'file_name' which I should fetch from child perl script.
So inside my parent_shell.sh script it will be like as follows,
perl my_perl_script.pl
file_name = 'variable' #from perl above perl script
Hope this is clear. Please let me know if it is not clear.
Thanks
Modifying the global %ENV hash in perl is equivalent to exporting variables in shell.
However, exporting variables in environment, in any language, only affects child processes, period. You can't modify parent process environment in any way.
The child script can only return anything by printing on standard output and standard error and by it's status, but that is a number 0-127 (well, it's a number 0-255, but shell can only reliably process the values up to 127).
If you just need one value from the perl script, simply print the value and use process substitution from the shell:
file_name=$(perl my_perl_script.pl)
if it is more, you can print a shell code to set the variables and use shell's eval, but make sure you quote the values correctly before printing from perl.

Perl: Testing an input reader?

Is there a way to automatically test using the standard Test etc. modules whether a Perl program is reading input from e.g. STDIN properly? E.g. testing a program that reads two integers from STDIN and prints their sum.
It's not 100% clear what you mean, I'll asnswer assuming you want to write a test script that tests your main program, which as part of the test needs to have test input data passed via STDIN.
You can easily do that if your program outputs what it reads. You don't need a special test module - simply:
Call your program your're testing via a system call
redirect both STDIN and STDOUT of tested program to your test script, using
IPC::Open2 module to open both sides via pipes to filehandles,
... OR, build your command to redirect to/from files and read/write the files in the test script
Check STDOUT from tested program that you collected in the last step to make sure correct values are printed.
If you want to test if STDIN is connected to a terminal, use -t, as in:
if( -t STDIN ){
print "Input from a terminal\n";
}else{
print "Input from a file or pipe\n";
}
See http://perldoc.perl.org/perlfunc.html#Alphabetical-Listing-of-Perl-Functions

How to debug a perl script used inside another perlscript?

How to debug a perl script used inside another perlscript. We can debug both separately. Is it possible to debug in one step?
Ex:
!/user/bin/perl
my $param= 8;
my #res=\`perl extract.pl $config`;
print "The results is .... #res\n";
Similarly, can we debug the perl scripts used inside shell script?
Thanks.
You can add -d switch to the shebang line of the script you are invoking:
#!/usr/bin/perl -d
A dynamic solution:
my $dswitch = $INC{"perl5db.pl"} ? "-d" : "";
my #res=`perl $dswitch extract.pl $config`;
$INC{"perl5db.pl"} is true when you are using the debugger, and false when you are not.
The "correct" thing to do would be to change your design so you are not calling the other script through a system command. Then you would have a single debugging environment.
The best design would be to make extract.pl into a module.
You could also use the do command to import the code from the other file: do 'extract.pl'. Then the only change needed would probably be the way you pass $config in.
Either of these approaches would be quite simple to implement and would have other benefits for continued development. Maybe you have a good reason not to do it this way, but I would consider this first if you haven't already.
Just debug extract.pl passing in the value in $config. If you don't know what it is, the age-old printf will do that for you.
say "\$config='$config'";
And then do:
perl -d extract.pl 'Stuff that printed in config'.
As the two are isolated processes, the only communication is what is passed on the command line and what is printed by the called script. So the called script should be capable of being tested without the calling script. (Unless you've set up some sort of IPC or shared memory or something tricky like that.)