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

#!/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.

Related

Check whether string starts with "!" in POSIX sh

Trying to create a condition based on whether the line starts with an "!".
Note: this is sh not bash
#!/bin/sh
if [ $line = "!*" ] ;
then
echo "$0: $line has !"
else
echo "$0: $line has no !"
fi
In POSIX test, = performs exact string comparisons only.
Use a case statement instead.
case $line in
"!"*) echo "$line starts with an exclamation mark" ;;
*) echo "$line does not start with an exclamation mark" ;;
esac
If you really want to put this in an if, you can do that:
if case $string in "!"*) true;; *) false;; esac; then
echo "$line starts with an exclamation mark"
else
echo "$line does not start with an exclamation mark"
fi
You can use the standard POSIX parameter substitution syntax.
${var#repl} will remove the repl from the beginning of the content of the $var variable.
So, you'll have:
$ var=test
$ echo ${var#t}
est
$ echo ${var#X}
test
So, in order to have a simple if statement to check if a variable starts with a string (! in your case), you can have:
#!/bin/sh
if test "$line" = "${line#!}"; then
echo "$0: $line has no !"
else
echo "$0: $line has !"
fi
PS: test ... is equivalent to [ ... ], so the above script is exactly the same as
#!/bin/sh
if [ "$line" = "${line#!}" ]; then
echo "$0: $line has no !"
else
echo "$0: $line has !"
fi
Could be as simple as echo "$STR" | cut -c -1.
#!/bin/sh
STR="!abcd"
if [ "!" = $(echo "$STR" | cut -c -1) ]; then
echo "true"
fi

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 run a shell command in perl in backticks when command also has backticks

example.
$output= `eval `environment` ; echo $Variable` ;
i want to execute this command
eval `environment` ; echo $Variable
in a perl script.
$output= `eval `environment` ; echo $Variable` ;
Use the qx// form from the "Quote-like Operators":
my $output = qx{eval `environment` ; echo $Variable};
But that still probably wouldn't do what you want, since $Variable would be already evaluated and interpolated by Perl. To fix that:
# single quotes:
my $command = q{eval `environment` ; echo $Variable};
# and then execute it:
my $output = qx{$command};
Alternatively, a little hack:
my $output = qx'eval `environment` ; echo $Variable';
When the ' is used as the character to the quote-like operators, it inhibits the variable interpolation.
You may use Backtiks "here documents" - see Backtics sub section in man perlop for details. $ sign must be escaped if you want to avoid variable expansion by perl.
#!/usr/bin/perl
use strict;
use warnings;
my $output = <<`END`;
eval `environment` ; echo \$Variable
END
print $output;

Embedded Perl in Shell Script - Returning value to Parent

For some reason I need to run a perl script in Bash. But there is a counter in perl which I want to use back in the shell script (parent). But for some reason I am not able to fetch it.
Can somebody please help me with this? (The only alternative I am doing is writing the perl return code in a file and then reading the file in shell script (parent) to fetch the value).
#!/bin/sh
cnt=1
echo "In Bash (cnt: $cnt)"
perl - $cnt <<'EOF'
#!/usr/bin/perl -w
my $cnt=shift;
while ($cnt<100) {
$cnt++;
}
print "In Perl (cnt: $cnt)\n";
exit $cnt;
EOF
echo "In Bash (cnt: $cnt)"
Output:
$ ./testPerl
In Bash (cnt: 1)
In Perl (cnt: 100)
In Bash (cnt: 1)
#!/bin/sh
cnt=1
echo "In Bash (cnt: $cnt)"
cnt=`perl -e '
my $cnt=shift;
while ($cnt<100) {
$cnt++;
}
print $cnt;
exit' $cnt`
echo "In Bash (cnt: $cnt)"
#askovpen answered this before me. I want to demonstrate that you can still use a heredoc if you want:
#!/bin/sh
cnt=1
echo "before (cnt: $cnt)"
cnt=$(
perl -l - $cnt <<'EOF'
$x = shift;
$x++ while $x < 100;
print $x;
EOF
)
echo "after (cnt: $cnt)"
I changed perl's variable name to make it clear the variable isn't shared at all
#!/bin/sh
cnt=1
echo "In Bash (cnt: $cnt)"
perl - $cnt <<'EOF'
#!/usr/bin/perl -w
my $cnt=shift;
while ($cnt<100) {
$cnt++;
}
print "In Perl (cnt: $cnt)\n";
exit $cnt;
EOF
cnt=$?;
echo "In Bash (cnt: $cnt)"

How to Convert While/Case statements in bash to perl

Here is the loop in bash:
while [ $# -ge 1 ]; do
case $1 in
-a)
shift
NUM_AGENTS=$1
;;
-h)
shift
HOST_NAME=$1
;;
-t)
shift
TIME_STAGGER=$1
;;
-un)
shift
USER_NAME=$1
;;
-pw)
shift
USER_PASS=$1
;;
-p)
shift
TARGET_PAGE=$1
;;
-s)
shift
COMMON_SID=$1
;;
esac
shift
done
How can i convert this in perl so that the argument would populate the values in the command line
php loadAgent_curl.php $NUM_AGENTS $HOST_NAME $procStartTime $i $TARGET_PAGE $reqlogfile $resplogfile $USER_NAME $USER_PASS $execDelay $COMMON_SID &
------- appended to question:
this certainly helps, and i really appreciate it, is there any way to access these parameters outside the getOptions ? here is rest of the bash script: my $i="0";
my $startTime=date +%s;
startTime=$[$startTime+$NUM_AGENTS+10]
my $PWD=pwd;
my $logdir="\$PWD/load-logs";
system(mkdir $logdir/$startTime);
my $reqlogfile="$logdir/$startTime/req.log";
my $resplogfile="$logdir/$startTime/resp.log";
print "\n";
print "##################\n";
print "LAUNCHING REQUESTS\n";
print " HOST NAME : \$HOST_NAME\n ";
print " TARGET PAGE : \$TARGET_PAGE\n ";
print " # AGENTS : \$NUM_AGENTS\n ";
print " EXECUTION TIME : \$startTime (with random stagger between 0 and \$TIME_STAGGER seconds)\n ";
print " REQ LOG FILE : $reqlogfile\n ";
print " RESP LOG FILE : $resplogfile\n ";
print "##################\n";
print "\n";
#
#
highestStart=$startTime
$startTime += $ARGV[0] + 5;
my $dTime = localtime( $startTime );
print "\n##################\nLAUNCHING REQUESTS\n
COUNT: $ARGV[0]\n
DELAY: | 1 \n
The scripts will fire at : $dTime\n##################\n\n";
while ( $ARGV[0] > $i )
{
$i++;
system("php avtestTimed.php $ARGV[0] $ARGV[2] $startTime");
print "RUN system('php avtestTimed.php $ARGV[0] $ARGV[2] $startTime'); \n";
sleep 1;
}
#
#
while [ $NUM_AGENTS -gt "$i" ]
do
i=$[$i+1]
execDelay=$((RANDOM % $TIME_STAGGER))"."$((RANDOM % 100))
procStartTime=$[$startTime]
procStartTime=$[$startTime+$execDelay]
if [ $procStartTime -gt $highestStart ]
then
highestStart=$procStartTime
fi
echo "STATUS: Queueing request $i with a delay of $execDelay seconds"
echo " '--> COMMAND: php loadAgent_curl.php $NUM_AGENTS $HOST_NAME $procStartTime $i $TARGET_PAGE $reqlogfile $resplogfile $USER_NAME $USER_PASS $execDelay $COMMON_SID"
php loadAgent_curl.php $NUM_AGENTS $HOST_NAME $procStartTime $i $TARGET_PAGE $reqlogfile $resplogfile $USER_NAME $USER_PASS $execDelay $COMMON_SID &
sleep 1
done
echo "STATUS: Waiting for queued requests to be ready"
while [ date +%s -lt $startTime ]
do
sleep 1
done
#
echo "STATUS: Waiting for last request to issue"
while [ date +%s -lt $highestStart ]
do
sleep 1
done
#
echo "STATUS: Last response issued"
#
echo "STATUS: Waiting for response log file to be created"
while [ ! -e "$resplogfile" ]
do
sleep 1
done
#
while [ wc -l "$resplogfile"| awk '{print $1'} -lt $NUM_AGENTS ]
do
#echo "(wc -l "$resplogfile"| awk '{print $1'} of $NUM_AGENTS responses recorded)"
sleep 1
done
echo "STATUS: FINISHED"
while true; do
read -p "Do you wish to view the request log? [y/n]" yn
case $yn in
[Yy]* ) cat $reqlogfile; break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
while true; do
read -p "Do you wish to view the response log? [y/n]" yn
case $yn in
[Yy]* ) cat $resplogfile; break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
Getopt::Long library is a standard Perl way to process command line options.
Something like this will work. Not tested - caveat emptor!
Please note that since your PHP parameters are a mix between command line options AND some unidentified variables, I have designed the first example so that ALL the possible options should be stored in %args hash (e.g. your program should use $args{procStartTime} instead of $procStartTime). This allowed me to make it very short and generic.
If this is hard to read/understand, I also have a second example that's more straightforward but less generic
use Getopt::Long;
my #php_arg_order = qw(a h procStartTime i p reqlogfile
resplogfile un pw execDelay s);
my %args = map {$_ => ""} #php_arg_order;
$args{procStartTime} = "something";
$args{reqlogfile} = "a.log";
# More defaults for variables NOT passed in via command line.
# Populate them all in %args as above.
# Now load actual command line parameters.
GetOptions(\%args, map { "$_=s" } #php_arg_order) or die "Unknown parameter!\n";
system(join(" ",
"php", "loadAgent_curl.php",map { $args{$_} } #php_arg_order}, "&"));
A second, less advanced but more direct option is:
use Getopt::Long;
my %args = ();
# Now load actual command line parameters.
GetOptions(\%args,
"NUM_AGENTS|a=s"
,"HOST_NAME|h=s"
,"USER_NAME|un=s"
# ... the rest of options
# The "XXX|x" notaion allows using alias "-x" parameter
# but stores in $args{XXX} instead for better readability
) or die "Unknown parameter!\n";
system("php loadAgent_curl.php $args{NUM_AGENTS} $args{HOST_NAME} $procStartTime $i $args{TARGET_PAGE} $reqlogfile $resplogfile $args{USER_NAME} $args{USER_PASS} $execDelay $args{COMMON_SID} &");