Execute a command using a perl script - perl

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&`;

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.

How to call shell script from perl script

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");

syntax error in perl script for linux

I have written a very simple perl script for Linux to determine the current user logged on.
However I keep getting the following error when trying to run it:
bash: use: command not found
bash: my: command not found
bash: ./test.pl: line 9: syntax error near unexpected token `else'
bash: ./test.pl: line 9: `} else {'
This is my code:
#!/usr/bin/perl
use strict;
my $loginName = '';
if ($^O =~ /MSWin/i)
{
$loginName = getlogin;
} else {
#else it is unix
$loginName = getpwuid($<);
}
print $loginName;
I have tried to google this but I dont see what I am doing wrong with my if statement? It works fine on Windows.
Thank you
You are invoking the script incorrectly: these errors are clearly from bash, while perl should be running the script instead.
I don't know how you're running it now, but (assuming its filename is mywhoami) you can always invoke perl explicitly:
perl mywhoami
It should also work to make it executable
chmod a+x mywhoami
and then execute it:
./mywhoami
I think it is something it the way you run the script.
Please try to run it as follow:
$perl <script.pl>

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

jsvc (tomcat) does not daemonize properly when run with backticks and then defuncts

In debian lenny, when running /etc/init.d/tomcat5.5 start, it runs jsvc and expects it to daemonize itself.
From a simple bash shell, this works fine.
However, from a script, this gets completely stuck:
For example, the following works like a charm:
#!/usr/bin/perl
my $cmd = '/etc/init.d/tomcat5.5 start';
system($cmd);
However, the following gets stuck as jsvc does not daemonize:
#!/usr/bin/perl
my $cmd = '/etc/init.d/tomcat5.5 start';
`$cmd`;
It also gets stuck when running it using backticks in bash:
#!/bin/bash
CMD='/etc/init.d/tomcat5.5 start'
`$CMD`
Is this a bug in jsvc? Any idea why this works in a shell or using system() , but not using backticks? I am actually getting defunct/zombie processes because of this issue.
Just a hunch -- for a job to become a daemon it needs to close any file descriptors that were opened in its parent process. Perhaps this is easier to do with system than with backticks/readpipe, though I can't come up with any good reasons why that would be so. What if you used the backticks like:
`$CMD < /dev/null > /dev/null 2>&1`
Backticks will evaluate to the output of the command, if there's lots of data, you may fill the buffer. No need to use the backticks if you don't want to evaluate or catpure the output in the script itself.
In example, this bash script should work:
#!/bin/bash
CMD="/etc/init.d/tomcat5.5 start"
# note no backticks
$CMD
Also please define "daemonize"? You want this nohup'd and asynchronous?