I have written a small script from which I'm calling another script.
Code:
package.PL
use strict;
no warnings 'experimental::smartmatch';
use feature qw(switch);
print"\nPlease enter Perl Installation Path\n";
my $path=<>;
$path=~ s/^\s+|\s+$//;
while(1){
print "\nEnter your Choice : \n";
print "1.Premigration Script for active records\n";
print "2.Premigration Script for archival records\n";
print "3.Post Migration Script\n";
print "4.Cleanup Script\n";
print "5.Exit\n";
my $input=<>;
given($input){
when(1) {system("$path/perl export_from_ddts.pl configfile_active.ini");system("$path/perl convert_to_csv.pl configfile_active.ini");}
when(2) {system("$path/perl export_from_ddts.pl configfile_archived.ini");system("$path/perl convert_to_csv.pl configfile_archived.ini");}
when(3) {system("$path/perl post_migration.pl configfile_active.ini");}
when(4) { system("$path/perl cleanup.pl");}
default {
if($input > 4){
print "\nYou want to exit the menu? y/n\n";
my $state=<>;
$state =~ s/^\s+|\s+$//g ;
if($state eq 'y'){
last;
}
else{
continue;
}
}
}
}
}
If I call any script from Package.pl, It is running twice.
For example: If I select option 1 to run pre-migration script for active projects, I'm getting same output twice.
perl version:5.18.1
I'm running on another perl installation(not system perl) in linux.
At first you could use $^X for the PATH of Perl or $EXECUTABLE_NAME when you use use English
You see the output twice? - Your code is ok. Why do you use no warnings 'experimental::smartmatch when you don use any smartmatch operators?
I have tried to reconstruct your code but its working for me.
Related
I am working on a legacy and confined system, where I do not have any known way to get anything installed. Now, I need to run multiple SHELL commands on a same shell. For example, the 2nd command should be aware of any changes done to the SHELL environment by the previous command. (like Environment variable manipulation). The system does not have perl expect module available, so I am trying to use IPC::Open3 to open shell and run commands and checking the stdout and stderr for expected strings. This works fine, for only the first function call of runner function and not the 2nd call.
Here is my code, dumb down version:
#!/usr/bin/perl
use IPC::Open3;
use utf8;
#First expect script
my $pid = open3(*IN, *OUT, *ERR, "/bin/bash");
my #output_arr;
my #error_arr;
sub runner {
my ($PID,$CMD,$REGEX) = #_;
print IN "$CMD\n";
close IN;
waitpid $PID, 0;
my $cmd_output = do { local $/; <OUT> };
my $cmd_error = do { local $/; <ERR> };
if ($cmd_output =~ m/$REGEX/ or $cmd_error =~ m/$REGEX/) {
print "$CMD output contains $REGEX\n"
}
else
{
print "$CMD output does not contain $REGEX, command output is $cmd_output ,error is $cmd_error\n"
}
push #output_arr, $cmd_output;
push #error_arr, $cmd_error;
return ($cmd_output, $cmd_error);
}
# This data will come from other progams.
#this works
my ($date_output, $date_error) = runner($pid, "LC_ALL=C date", qr/2023/s);
#this never works
my ($date_output, $date_error) = runner($pid, "LC_ALL=C date", qr/Jan/s);
The output:
LC_ALL=C date output contains (?^s:2023)
LC_ALL=C date output does not contain (?^s:Jan), command output is ,error is
I am writing a perl code to upload code from a repro to a directory(jsvn update . a shell comand in my case) . I wanted that while the check in is going on, the result should display in stdout ('jsvn update .' does show that but i have to keep on looking at the monitor in case of any error and incase of error i have to give a clean up and start the process again.) I wrote a program for that, but it doesnot displays output to screen. The cursor keeps blinking and i know the process is going on background, but i want to have the results also displayed to stdout. Please help me.
#!usr/bin/perl
use Capture::Tiny qw/tee/;
sub code(){
`jsvn cleanup .`;
($stdout, $stderr, #result) = tee { system( "jsvn update ." ) };
print "#result\n";
}
code();
if($stderr){
code();
}else{
print "The checkout has been done successfully \n";
exit;
}
If you wanna use IPC::System::Simple you could grab exit values through $EXITVAL doing something like this:
...
use IPC::System::Simple qw[capture $EXITVAL];
use feature qw[switch];
...
my #result = capture('jsvn update .');
given ($EXITVAL) {
when (0) {
print "Ok\n";
}
when (1) {
}
..
when (N) {
}
}
...
Before posting my question to the ActiveState forum, I'd like to try luck here :)
I'm trying to convert a simple script of mine to .exe file using Perlapp (version 8.1). The Perl script works fine and it seems Perlapp also did its job successfully.
But the converted .exe file has some weird behavior, which, I believe, must be related to utf-8 encoding. For example, the Perl script would yield the result like:
hàn huáng zhòng sè sī qīng guó
But running the executable file would give me only this:
h hu zh s s q gu
I've already configured Perlapp so that utf8.pm is explicitly added but the problem just refuses to go away. I've tried something else. For example,
binmode DATA, ":utf8";
and
">:encoding(utf8)"
but without any luck;
Can anyone kindly give me some hint as to what might be the reason? Thanks like always :)
I can post the whole code here but it seems unnecessary so I just paste some snippets of the code that I think is relevant to the problem:
use utf8;
%zidian = map {chomp;split/\s+/,$_,2} <DATA>;
open my $in,'<:utf8',"./original.txt";
open my $out,'>:utf8',"./modified.txt";
if ( $code~~%zidian) {
$value = lc$zidian{$code};
}
__DATA__
3400 Qiū
3401 TIǎN
3404 KUà
3405 Wǔ
And one more thing, I'm running ActivePerl 5.10.0.on Windows XP (Chinese Version) and the script is saved as utf-8 encoding without BOM. PerlApp cannot handle a script that has BOM.
Edit
If I were to give a workable snippet, then I suppose it's like giving the whole code because I'm using three inter-connected sub-routines, which I take with some modifications from Lingua::han::Pinyin module and Lingua::han::Utils module.
#! perl
# to make good vertical alignment,
# set font family to SonTi and font size to Four(12pts)
use utf8;
sub Unihan {
my $hanzi = shift;
my #unihan = map { uc sprintf("%x",$_) } unpack ("U*", $hanzi);
}
sub csplit {
my $hanzi = shift;
my #return_hanzi;
my #code = Unihan($hanzi);
foreach my $code (#code) {
my $value = pack("U*", hex $code);
push #return_hanzi, $value if ($value);
}
return wantarray ? #return_hanzi : join( '', #return_hanzi );
}
%zidian = map {chomp;split/\s+/,$_,2} <DATA>;
sub han2pinyin {
my $hanzi = shift;
my #pinyin;
my #code = Unihan($hanzi);
foreach $code (#code) {
if ( $code~~%zidian) {
$value = lc$zidian{$code};
}
else {
$value = " ";
}
push #pinyin, $value;
}
return wantarray ? #pinyin : join( '', #pinyin );
}
open $in,'<:utf8',"./original.txt";
seek $in, 3,0;
open $out,'>:utf8',"./modified.txt";
while(<$in>){
s/(.{18})/$1\n/g;
push #tmp, $_;
}
foreach (#tmp){
my #hanzi;
my #pinyin;
#hanzi = csplit($_);
my $hang = join "", #hanzi;
#pinyin = han2pinyin($hang);
for ( my $i = 0; $i < #hanzi && $i < #pinyin; ++$i ) {
if ( $hanzi[$i] =~ /[\xEFBC8C]|[\xE38082]|[\xEFBC81]|[\xEFBC9F]|[\xE2809C]|[\xE2809D]|[\xEFBC9A]/ ) {
splice(#pinyin, $i, 0," ");
}
}
printf $out "%-7s" x #pinyin, #pinyin;
print $out "\n";
printf $out "%-6s" x #hanzi, #hanzi;
print $out "\n";
}
__DATA__
3400 Qiū
3401 TIǎN
3404 KUà
3405 Wǔ
ActiveState hasn't given me any help yet. Whatever. Now I've figured out a workaround for my problem and this workaround looks very weird.
First I added some otherwise useless utf-8 encoded characters to my DATA section, like the following:
__DATA__
aardvark 'ɑ:dvɑ:k
aardwolf 'ɑ:dwulf
aasvogel 'ɑ:sfәugәl
3400 Qiū
3401 TIǎN
3404 KUà
3405 Wǔ
And then I removed the use utf8; pragma from my script;
and then I removed the utf8 flag from the following line of code:
open $out,'>:utf8',"./modified.txt";
Now it becomes
open $out,'>',"./modified.txt";
But I had to let the following line of code unchanged:
open $in,'<:utf8',"./original.txt";
Then everything was okay except that I'd receive "wide characters in print" warnings. But I added another line of code:
no warnings;
And then I Perlapped my script and everything worked fine :)
This is really strange. I'm suspecting this problem is somehow OS specific. It's also quite likely that there's something wrong with my Windows system. And I also tried Perl2exe and the compiled executable gave me some "memory 0010c4 cannot be read" error. Whatever. My problem is somehow fixed by myself :)
One way I found is to check if the Perl Debugger is "loaded" by checking for defined($DB::single) and assuming Komodo is active, if $DB::single is defined..
But this might also mean the script is legitimately running as perl -d under the "standalone" debugger.
#!/usr/local/ActivePerl-5.10/bin/perl
use strict;
use warnings;
use feature qw/say switch/;
# detect debugger ..
SayDebugerStatus();
sub SayDebugerStatus {
print "Debugger ";
given ($DB::single) {
when (undef) {
say "not loaded.";
}
when (0) {
say "loaded but inactive";
}
default {
say "loaded and active";
}
}
return defined($DB::single) ? 1:0;
}
zakovyrya's suggestion leads to:
if ( grep( /.*Komodo\ IDE\.app/g, values %INC) ){
say "Komodo is running"
} else {
say "Komodo is not running"
};
But is there another way?
UPDATE today my isKomodo() routine failed. Some investigation showed, that IT changed my global path settings from "long" to "short" names (this is under Windows) .. there nolonger is a "KOMODO" string in the %INC hash..
I'm looking for a replacement.
What does your %INC contain when you launch script under Komodo? There is a good chance that some Komodo-specific modules are loaded.
It's better to print its content with:
use Data::Dumper;
print Dumper \%INC;
Seems like something like this is easier (for the script to know it's running under Komodo):
use Modern::Perl;
if (exists $ENV{'KOMODO_VERSION'}) {
say "Script is running under Komodo $ENV{'KOMODO_VERSION'} !";
} else {
say "script is not running in Komodo"
}
UPDATE(by 'lexu): KOMODO (7) now places KOMODO_VERSION in the environment
This question already has answers here:
How can I require an optional Perl module if installed?
(8 answers)
Closed 9 years ago.
I'm writing a small Perl script that depends on some modules that might be available, so during the installation I would have to check if everythings there. I could just write use some::module and see if an error comes up, but a short message like "You need to install some::module" would be more helpful for endusers.
I also could just search every directory in #INC, but as it's Perl, there has to be an easier way.
perl -MSome::Module -e ';'
Whoops, misread the question. I thought you wanted to know in a one-off instance, not discovering it in a recoverable manner. I always use something like this:
sub try_load {
my $mod = shift;
eval("use $mod");
if ($#) {
#print "\$# = $#\n";
return(0);
} else {
return(1);
}
}
Which you use like this:
$module = 'Some::Module';
if (try_load($module)) {
print "loaded\n";
} else {
print "not loaded\n";
}
How about:
die "Some::Module missing!" unless(eval{require Some::Module});
I have a little script that lists all the Perl modules on my system;
#!/usr/bin/perl
use ExtUtils::Installed;
my $instmod = ExtUtils::Installed->new();
foreach my $module ($instmod->modules()) {
my $version = $instmod->version($module) || "???";
print "$module -- $version\n";
}
Inside that foreach loop you might want to do some thing like;
my $match;
if ($module =~ /$match/) {
print "Found $match: $module\n";
}
I use something like this:
BEGIN {
my $module_name = shift; # #ARGV
our $module_exp = $module_name;
eval "use $module_name;";
}
$module_exp =~ s{::}{/}g;
foreach my $key ( grep { m/^$module_exp\./ } keys %INC ) {
print "$key => $INC{$key}\n";
}
But I use this more in the form of a korn shell function:
function wherperl
{
perl -M$1 <<EX_DOC
my \$module = '$1';
\$module =~ s/::/\\//g;
for ( keys %INC ) {
next unless m/^\$module\./;
print \$_ . ' => ' . \$INC{\$_} . "\n";
}
EX_DOC
}
I like to use the cpan utility:
% cpan -D YAML
YAML
-------------------------------------------------------------------------
YAML Ain't Markup Language (tm)
A/AD/ADAMK/YAML-0.70.tar.gz
/usr/local/perls/perl-5.10.0/lib/site_perl/5.10.0/YAML.pm
Installed: 0.68
CPAN: 0.70 Not up to date
Ingy dot Net (INGY)
ingy#cpan.org
This can be a little slow since it has to connect to a CPAN mirror to fetch some of the data, but I also have a local CPAN mirror. :)