Executing Command on child shell - perl

Here is the updated question
Script:
open (my $pipe, "| ptsetenv.sh $ProductType $Release");
print $pipe "genidasack.py -v --alignment=mips64 -a -s $WORKSPACE/dbgen/ose_signals_ADA.sdt -o $WORKSPACE/$Product/\n";
close ($pipe);
Command 2:
ptsetenv.sh $ProductType $Release # Sets Environment Variables and creates a Child Shell
Command 3:
genidasack.py -v --alignment=mips64 -a -s $WORKSPACE/dbgen/ose_signals_ADA.sdt -o $WORKSPACE/$Product/\n #this has to be executed on child Shell created by Command 2
Currently when i run the script within a perl script after first line child shell is invoked and script remains at child shell when type exit from child shell subsequent script lines are executed which is not what is needed!
HERE ARE CONTENTS OF ptsetenv.sh
envsetup.py $*
./export_env.sh
export_env.sh is the script which basically creates the child shell
Let me know if you need contects of export_env.sh
HERE ARE CONTENTS OF export_env.sh
has_dir()
{
if [ -d $1 ]; then
return 0
else
return 1
fi
}
has_dir $DXENVROOT
if [ "$?" != "0" ]; then
echo "Directory $DXENVROOT does not exist. Exiting the script."
exit -1
fi
echo "Environment set to ${DXENVNAME} ${DXENVVERSTR}"
echo $SHELL
$SHELL
echo "Exiting ${DXENVNAME} ${DXENVVERSTR} shell"

This will run a sequence of commands in the child shell:
system("Command 1; python script; Command 2");
You can also do:
system("Command 1");
system("python script");
system("Command 2");
This avoids creating a shell process if there are no special shell characters in the commands.
UPDATE:
Now that you've clarified that the python script starts a subshell, here's how to send a command to it:
open (my $pipe, "| Command 1; python script");
print $pipe "Command 2\n";
close ($pipe);

Related

How to run unix block command eg:if from perl

How to run a if block in unix from perl.
Eg:
location="/home/shon";
if [[ -f $location/sample.txt ]]
then
echo "file found...."
else
echo "Error in getting file"
exit 255
fi
from perl.
As suggested, this code is simple to translate into perl. Assuming you have something more complex, you can spawn a shell to run it: put the shell code in a quoted heredoc so that perl does not substitute the shell variables.
system 'bash', '-c', <<'END_SHELL_CODE';
location="/home/shon"
if [[ -f $location/sample.txt ]]; then
echo "file found...."
else
echo "Error in getting file"
exit 255
fi
END_SHELL_CODE
Try this
#! /usr/bin/perl
my $location ="/home/shon/sample.txt";
if (-f $location)
{
print "file found....";
}
else
{
print "Error in getting file";
}

How to suppress piped input sent to perl on command line?

At my comand prompt, I ran a grep and got the following result.
$ grep -r "javascript node"
restexample/NewsSearchService/V1/madonna_html.html:<!-- start empty javascript node for popup app fix -->
restexample/NewsSearchService/V1/madonna_html.html:<!-- end empty javascript node for popup app fix -->
Now, suppose I want to remove the "restexample" part. I can do that by using
print substr($_,13)
However, how when I pipe to perl, this is what I get -
grep -r "javascript node" | perl -pe ' print substr($_,11) '
/NewsSearchService/V1/madonna_html.html:<!-- start empty javascript node for popup app fix -->
restexample/NewsSearchService/V1/madonna_html.html:<!-- start empty javascript node for popup app fix -->
/NewsSearchService/V1/madonna_html.html:<!-- end empty javascript node for popup app fix -->
restexample/NewsSearchService/V1/madonna_html.html:<!-- end empty javascript node for popup app fix -->
As you can see, the piped input simply got echoed. How to prevent this?
Try
grep -r "javascript node" | perl -lpe '$_ = substr($_,11)'
or
grep -r "javascript node" | perl -lne 'print substr($_,11)'
Explanation: -p switch automatically prints current line ($_) while -n switch doesn't.
perl -MO=Deparse -lpe '$_ = substr($_,11)'
BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
$_ = substr($_, 11);
}
continue {
die "-p destination: $!\n" unless print $_; # <<< automatic print
}

NetworkManager dispatcher script

scripts in /etc/NetworkManager/dispatcher.d will got exec and parameters will be passed to the scripts by NetworkManager.
One of my laptop BIOS is malfunctioning, I have to manually sync the time, and do system upgrade BTW. I am working with a script to automate this task.
Here's the script:
#!/bin/sh
IF=$1
STATUS=$2
if [ "$STATUS"x != 'up'x -o "$(date +%Y)" -gt "2012" ] ;then
exit
fi
logger "==$0=="
wait_for_process(){
PNAME=$1
PID=`pgrep $PNAME`
while [ -z "$PID" ];do
logger "waiting $1 running for another 3 sec.."
sleep 3;
PID=`pgrep $PNAME`
done
logger "$1 is running!"
}
wait_for_process nm-applet
wait_for_process lxpanel
export DISPLAY=$(echo $DISPLAY | cut -c -2)
if [ -z $DISPLAY ];then
export DISPLAY=:0
fi
#below cmd will yield null string for $user
user=$(who | grep "$DISPLAY" | awk '{print $1}' | tail -n1)
#so I have to hardcode the user name:(
user=xxx
export XAUTHORITY="/home/$user/.Xauthority"
logger "Display $DISPLAY user $user"
su $user -c "xterm -e 'sudo /usr/bin/ntpd -qdg && sudo yaourt -Syua' &" || logger "cannot run xterm"
(the script is invoked before x window, run as root)
user=$(who | grep "$DISPLAY" | awk '{print $1}' | tail -n1) cannot find the login user name. But it works in xterm.
Can someone help?
I am using archlinux i686 + openbox + lxpanel
edit:
I want to find the real login user name, while the script is run by root.
Are you looking for the name of the user running the script? How about:
user=$( id -un )

get output of perl script from bash script and exit

From a bash script how can i execute a perl script get the output and exit if value is = 0?
Also in the perl script how do i return the value, do i just return it or do i print it?
#!/bin/bash
perl-script args && exit
If you want to continue running, the return value is in $?
Note that there is a distinction between the value returned by the perl script and the output of the script. To get the output of the script, use the $() operator:
#!/bin/bash
output=$(perl-script args)
echo The perl script returned $?
echo The output of the script was $output
To get a return code, use the exit function. Example:
Perl script:
if ($success) {
$return_value = 0;
} else {
$return_value = 1;
}
exit($return_value);
Bash script:
perl scriptname args > outfile && exit
That's assuming that you want to exit if the return value of the Perl script is 0 and you want so save the output of the Perl script in outfile. If the return value is not zero, it's stored in $?, you can save that value to a variable if you please.
Your perl script: foo.pl
#!/usr/bin/perl
# do something and then
exit 1;
And inside your bash script foo.sh:
#!/bin/bash
# do something and then call perl script
perl foo.pl
# check return value using $?
echo "perl script returned $?"

How can i convert the following bash script into a perl script

#!/bin/bash
i="0"
echo ""
echo "##################"
echo "LAUNCHING REQUESTS"
echo " COUNT: $2 "
echo " DELAY: $3 "
echo " SESSID: $1"
echo "##################"
echo ""
while [ $2 -gt "$i" ]
do
i=$[$i+1]
php avtest.php $1 $4 &
echo "EXECUTING REQUEST $i"
sleep $3
done
here is a better/modified script in bash
#!/bin/bash
i="0"
#startTime=`date +%s`
startTime=$(date -u +%s)
startTime=$[$startTime+$1+5]
#startTime=$($startTime+$1+5)
dTime=`date -d #$startTime`
echo ""
echo "##################"
echo "LAUNCHING REQUESTS"
echo " COUNT: $1 "
echo " DELAY: 1 "
#echo " EXECUTION: $startTime "
echo " The scripts will fire at : $dTime "
echo "##################"
echo ""
while [ $1 -gt "$i" ]
do
i=$[$i+1]
php avtestTimed.php $1 $3 $startTime &
echo "QUEUEING REQUEST $i"
sleep 1
done
Here's a direct translation
#!/usr/bin/env perl
use strict;
use warnings;
print <<HERE;
##################
LAUNCHING REQUESTS
COUNT: $ARGV[1]
DELAY: $ARGV[2]
SESSID: $ARGV[0]
##################
HERE
my $i = 0;
while($ARGV[1] > $i){
$i += 1;
system("php avtest.php $ARGV[0] $ARGV[3] &");
print "EXECUTING REQUEST $i\n";
sleep $ARGV[2];
}
But it would make more sense to read the command line parameters into variables named after what they're for and not rely on remembering argument ordering.
A brief errata in the conversion:
I use a here string to represent multiline text. I could also have put in multiple print statements to more closely mimic the bash version
In bash arguments are accessed as numbered variables, starting with $1 and going up. In Perl the argument list is represented by the array #ARGV, which is numbered starting at zero (like arrays in most languages). In both bash and Perl the name of the script can be found in the variable $0.
In Perl arrays are written as #arrayname when refering to the entire array, but they use $arrayname[index] when accessing array members. So the Perl $list[0] is like the bash ${list[0]} and the Perl #list is like the bash ${list[#]}.
In Perl variables are declared with the my keyword; the equivalent in bash would be declare.
I've used the system function for spawning background processes. Its argument can be simply the command line as you might use it in bash.
Unlike echo, print requires to be told if there should be a newline at the end of the line. For recent versions of Perl the say function exists which will append a newline for you.
The Perl sleep function is pretty self-explanatory.
EDIT: Due to a typo $i in the print statement had been represented as $ni leading to runtime errors. This has been corrected.