How to run unix block command eg:if from perl - 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";
}

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

Trying to clone a ksh function with little modification with a one liner perl

I've a short ksh script that is often generated automatically. However, it's missing some stuff and I want to be able to "fix it" like I want by running a simple 1 liner perl to sed it.
Let say that the ksh contains the following function:
foo()
{
/some/command param1
if [[ $? -eq 0 ]]
then
/some/other/command stop param1
fi
/some/command param2
if [[ $? -eq 0 ]]
then
/some/other/command stop param2
fi
#...
}
and what I really want looks like this
foo_force()
{
/some/command param1
if [[ $? -eq 0 ]]
then
/some/other/command stop -f param1
fi
/some/command param2
if [[ $? -eq 0 ]]
then
/some/other/command stop -f param2
fi
#...
}
foo()
{
/some/command param1
if [[ $? -eq 0 ]]
then
/some/other/command stop param1
fi
/some/command param2
if [[ $? -eq 0 ]]
then
/some/other/command stop param2
fi
#...
foo_force
}
So far I've been able to get something "close", ie 2 perl commands, which would be ok with me. However, the second command only replace the last stop by a -f stop... which is not what I'm looking for.
/usr/bin/perl -i -pe "BEGIN{undef $/;}; s/^(foo)(\(\)\n{.*\n)}/\1_force\2}\n\n\1\2\t\1_force\n}/gms" /tmp/foo.ksh
/usr/bin/perl -i -pe "BEGIN{undef $/;}; s/^(foo\(\)\n{.* stop)( .*\n})/\1 -f\2/gms" /tmp/foo.ksh
This might work for you (GNU sed):
sed -i '/^foo()/{:a;$!N;/\n}/!ba;h;s/^foo/&_force/;s/stop /&-f /g;s/$/\n/p;g;s/\n}/\n\n foo_force&/}' /file
Using perl
perl -0777 -i -pe '
s{(^foo\(\).*?\n\})}{
my $foo = my $force = $1;
$foo =~ s/\}$/ foo_force()\n\}/;
$force =~ s/^foo\K/_force/;
$force =~ s/ stop \K/-f /g;
"$foo\n$force"
}mse;
' /tmp/foo.ksh

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

Executing Command on child shell

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

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.