How to call shell script from perl script - perl

I'm trying to call already saved shell script from perl script, but it's not working .
1.pl:
#!/usr/bin/perl
#!/bin/csh -f
use warnings;
use Shell;
system ("/bin/sh commands.sh");
commands.sh:
#!/bin/csh -f
echo "calling shell script from perl script";

If commands.sh is executable, then all you should need is:
#!/usr/bin/perl
system("/path/to/commands.sh")
If commands.sh does not have the executable flag set, then
#!/usr/bin/perl
system("/bin/csh /path/to/commands.sh");
All of the other code appears to be superfluous.

The path to the shell script changes now and then for me, so I keep it in a variable at the top of the script where it is easy to update:
our $pathToShellScript = '/path/to/script.sh';
system("/bin/sh $pathToShellScript");
Not sure why this errors:
sh: -c: line 0: unexpected EOF while looking for matching ''`
While the following works:
system ("/bin/sh", "$renamingScript");

Related

Perl command executing good when run on command line but not working in the Perl script

Below is the code I'm trying to execute. I have mentioned the line 266 in the code. I have added that code to remove the blank lines in the log file. I'm not sure whether we can run the perl command inside a Perl script. Is there another way that I can run this so that I can remove the blank lines in the log file?
Below is the error I'm getting while running through the Perl script:
syntax error at ./reportJBossErrors.pl line 266, near "n -e "
Execution of ./reportJBossErrors.pl aborted due to compilation errors.
Here is a portion of the code, showing line 266:
sub main {
readConfiguration($config_file);
$short_hostname = `hostname | cut -f 1 -d.`;
chomp $short_hostname;
getFileandInstance($short_hostname);
$yesterday = getYesterday();
validateEnvironment();
$log_file = getLogFile($FMASK,$yesterday);
perl -i -n -e "print if /\S/" $log_file; # 266 line. This is where I'm getting the compilation error
processFile($log_file);
$html_out = writeEmail();
sendEmail($CONFIG{"FROMADDR"},$CONFIG{"TOADDR"},"Normal",
"JBOSS",$short_hostname,$log_file,$CONFIG{ENVTYPE},$html_out);
}
You can not call the perl command inside a Perl program as if it were a Perl builtin function. You can use system to run an external command:
my $cmd = 'perl -i -n -e "print if /\S/"';
system "$cmd $log_file";
You need to be careful of quoting. Since you have a file name/path in the Perl variable $logfile, which you want to interpolate, that can go inside double quotes. Since you do not want to interpolate \S, that should go in single quotes.
You cannot invoke the perl executable inside a Perl program as if it were a Perl builtin function. Instead, use the list form of system to run an external command. Don't forget to check if the command succeeded:
my #cmd = (perl => '-i', '-n', '-e', 'print if /\S/', $log_file);
system(#cmd) == 0
or die "system #cmd failed: $?";
In general, I would recommend using the full path to perl rather than relying on $PATH.
Also, if you need to keep track of status etc, use Capture::Tiny to get both STDOUT and STDERR of the command you are running so that you can log error information.

Execute a command using a perl script

I have simple command in unix like
cat myfile.txt >&mytemp.txt&
The above command will simply create a copy of the file myfile.txt.
when i execute the command on the command line it returns me the process id like below:
> cat myfile.txt > & mytemp.txt &
[1] 769
>
I am forming the same command inside a perl script and calling it with system as below:
my $cmd="cat myfile.txt>&mytemp.txt&";
my $info = system("$cmd");
but the sytem command fails with the below error message:
sh: mytemp.txt: bad number
I even tried with escaping the > and &.But there is no change in the error message.
May i know the reason for this?where am i wrong here?
I'm pretty sure that you can't use the trailing & on this. If you want your program to continue while the command runs, then fork and have the child process run the call, then exit. Possibly exec can do this, though I haven't tried doing that with output redirection before...
Like the message says, that's not a valid sh command. Is it perhaps a csh command?
system('csh', '-c', $cmd);
Try this:
perl -e "`cat myfile.txt>&mytemp.txt&`;"
It's executing the command and returning the command output.
So it's possible to do:
#!/usr/bin/perl
my $content = `cat /etc/passwd`;
print $content;
If you put the code into a perl script:
cat-test.pl
#!/usr/bin/perl
use strict;
use warnings;
my $res = `cat myfile.txt>&mytemp.txt&`;

using export and perl -c in perl scripting

Since export cannot be used with a Perl script I've used the environment variable.
This code doesn't return any error but the command perl -c to check the syntax of the .pm file does not print the output.
myscript.pl
$ENV{'PATH'}='C:/Users/abc/Desktop/mno/wwwww/scripts/lib/perl/';
system("perl -c ContentModifySeasonPassOverlayRecord.pm");
Let me make another guess at what you want to do:
You want to batch syntax-check all your Perl modules, maybe in a cronjob. The script you are using to do that is located somewhere outside your working directory (where your framework sits). The scripts you want to check also sit somewhere else.
What you need to do is run the perl -c command from where the lib (framework) is, so that the working directory for the script while running has the lib files. You need to change the working directory before doing your perl -c call, and you need to include the full path to your scripts in the call.
#!/usr/bin/perl
use strict; use warnings;
# Change current working directory to where the framework is
chdir('/home/user/Desktop/QWARTS-0.6/autoinfra/lib/perl/');
# Run the perl -c command for each of your scripts you want to check
foreach my $script (qw(ContentModifySeasonPassOverlayRecord.pm otherfiles.pm)) {
system("perl -c /path/to/your/scripts/$script");
}
#!/usr/bin/perl
use warnings;
use strict;
system("perl -c /root/.cpan/build/DateTime-TimeZone-1.31-oqQt_7/lib/DateTime/TimeZone/America/Noronha.pm");
I don't see how it doesn't work?
# ./errr.pl
/root/.cpan/build/DateTime-TimeZone-1.31-oqQt_7/lib/DateTime/TimeZone/America/Noronha.pm syntax OK
I think you are doing a wrong way to execute a perl script with in perl script
here is the right way of executing a perl script with in perl script
use strict;
use warnings;
use IPC::System::Simple qw(system capture);
# Run a command, wait until it finishes, and make sure it works.
# Output from this program goes directly to STDOUT, and it can take input
# from your STDIN if required.
system($^X, "yourscript.pl", #ARGS);
# Run a command, wait until it finishes, and make sure it works.
# The output of this command is captured into $results.
my $results = capture($^X, "yourscript.pl", #ARGS);
And to check the errors in a module , You can just 'use' the module in your perl script and run the script in an usual way , if it has errors it will throw to stdout
If you want to test large number of perl modules you can build a shell script for that purpose .
#!/bin/sh
// List all modules
MODULES="Data::Dumper Foobar::Test"
for i in $MODULES ; do
if $(perl -M$i -e '1;' >/dev/null 2>&1 ); do
echo "Ok."
else
echo "No."
fi
done

Executing perl code inside shell script using eval

I came across the following example. I tried to google but could not find much so I'm posting this question here.
What is the benefit of executing the perl script like this?
How can we make the shell script work like a "normal" shell script once we are through executing the perl code?
Here's the code:
#!/bin/ksh
#! -*- perl -*-
eval 'exec $PERLLOCATION/bin/perl -x $0 ${1+"$#"} ;'
if 0;
print "hello world\n";
# how can I make it behave like a "normal" shell script from this point onwards? What needs to be done?
# echo "hello world" ### this results in error
This idiom is described in the perlrun documentation.
The -x switch scans the whole file and ignores anything that appears before the first line that begins with #! and also contains the word perl.
It means that your system will run the script with the Perl interpreter whether you invoke the script with perl or with a shell command (sh/bash/ksh/etc.)
That is,
$ perl this_script
and
$ sh this_script
will both run the script with perl.
To address your second question, this idiom has just about nothing to do with combining shell script and Perl script in the same file. There are a few different ways to approach that problem, but maybe the most readable way is to write in shell script, but use the shell's heredoc notation to invoke perl code.
#!/bin/bash
# this is a bash script, but there is some Perl in here too
echo this line is printed from the shell
echo now let\'s run some Perl
perl <<EOF
# this is now perl script until we get to the EOF
print "This line is printed from Perl\n";
EOF
echo now this is from the shell script again
1. If you start a Perl script in the usual way:
#!/usr/bin/perl
print "hello world\n";
the #! line will only work if the Perl interpreter is actually installed under /usr/bin. The perl/ksh bilingual script you show is a tricky kluge to make the script work even if perl is installed somewhere else. For more information, see e.g. this.
2. You can't. When the shell process encounters the exec command, it terminates and hands control over to perl. (Technically, it executes perl in place of the shell, without creating a new process.) The only way to run more shell commands after that would be to launch a new shell.
It's way simpler than what's already been posted.
#!$PERLLOCATION/bin/perl
doesn't work because the shebang (#!) line is interpreted by the kernel (not the shell), and the kernel doesn't do variable interpolation.
The code invokes ksh to expand the environment variable and to launch the specified installation of Perl.

Not able to call a perl script from a shell script

I am trying to call a perl script from a shell script and code looks like shown below...
shell script test_sh
#Call the script
test2.pl ${PARTITION_ID} ${VNG_USER} ${VNG_PASSWORD} ${VNG_INSTANCE}
if [ $? -ne 0 ]
then
OP1ExitStatus -6
fi
while execution getting below error message:
./test_sh[142]: test2.pl: not found
Failed in test_sh
permission given to both files are 755.
But when i and calling test2.pl directly from the command line by passing all arguments it runs successfully.
I tried with below command as well :
#Call the script
perl test2.pl ${PARTITION_ID} ${VNG_USER} ${VNG_PASSWORD} ${VNG_INSTANCE}
if [ $? -ne 0 ]
then
OP1ExitStatus -6
fi
but it is also not working.
please let me know how to proceed in order to run it successfully.
From the command line you're invoking perl test2.pl directly. From the script you're assuming that (1) test2.pl is executable and (2) . is in $PATH somewhere. I would use the direct perl invocation in the script, at least for now.
check your shebang, eg #!/bin/bash. you may also want to try using the full path of your Perl executable.
That usually means that the path to perl in the shebang line at the top of the Perl script is wrong (assuming that the file has execute permission for you).
Try using:
#!/usr/bin/env perl
Your shell script is unable to find your test2.pl. You need to give the full path of test2.pl in your shell script or ensure it is in your $PATH.