How do I port a shell script to Perl? - perl

This is a shell script , How do I accomplish the same thing in Perl?
prfile=~/sqllib/db2profile
profile()
{
if [ -f $prfile ] && [ "$prfile" != "" ];
then
. $prfile
else
read -p "Enter a valid Profile : " prfile
profile
fi
}
profile
Here it checks for the profile file , if found it executes it with . $prfile else it again asks user for the proper profile file
Update
#!/usr/bin/perl
use strict;
use warnings;
my $profile = "$ENV{'HOME'}/sqllib/db2proile";
# default profile
while (not -e $profile) { # until we find an existing file
print "Enter a valid profile: ";
chomp($profile = <>); # read a new profile
}
qx(. $profile);
This worked. I want the home directory to be dynamic rather than hardcoded as they differ for different machines. I'm just trying to accomplish with Perl what I have achieved with shell.

If I understand your objectives, I don't think you can use perl to accomplish this because perl will be running as a child process and it can not change the environment of your shell (it's parent process). Maybe this would work for you (untested, off the cuff)?
prfile=~/sqllib/db2profile
if [ -s "$prfile" ] ; then
. "$prfile"
else
while true ; do
read -p "Enter a valid Profile : " prfile
if [ -s "$prfile" ] ; then
. "$prfile"
break;
fi
done
fi

Related

validate only alphabets using shell script in busybox

I want to validate a string which should only be Alphabets (Capital/Small). I can do it in Linux easily using Bash or Shell, but not able to validate in Busybox (OpenWRT). My piece of code is
...
#!/bin/sh
. /usr/share/libubox/jshn.sh
Info=$(cat /root/Info.json)
json_load "$Info"
json_get_var value plmn_description
echo "$value"
if [[ "$value" == [a-zA-Z] ]] ;then
echo "Valid"
else
echo "Invalid information"
fi
...
You can use case conditional construct like this:
case "$value" in
*[!a-zA-Z]*) echo invalid information ;;
*) echo valid
esac
Using Busybox awk:
$ busybox awk '{ # using busybox awk
for(i=1;i<NF;i++) # iterate all json record fields (not the last, thou)
if($i=="\"plmn_description\":" && $(i+1)~/^\"[a-zA-Z]+\",?$/) {
ret="Valid" # if "plmn_description": is followed by "alphabets"
exit # exit for performance
}
}
END {
print (ret?ret:"Invalid") # output Valid or Invalid
}' Info.json # process the json file
Output:
Valid

Code fails with stdin from SED

I have a bash script that finds files with particular extension and then pass the files into a function that checks every line in the file for only files that contain a library imported. For example:
function testing() {
while IFS='' read -r line; do
if [[ "$line" =~ .*log\" ]]; then
echo "log is imported in the file" $1
break
else
echo "log is not imported in the file" $1
break
fi
done < <(sed -n '/import (/,/)/p' "$1")
}
function main() {
for file in $(find "$1" -name "*.go"); do
if [[ $file == *test.go ]]; then
:
else
var1=$(testing $file)
echo "$var1"
fi
done;
}
main $1
The problem is the script works without the else block in the testing function but with the introduction of the else block in the testing function it just defaults to echoing the log is not imported in the file blah even if log is used in some of the files.
Any idea(s) on what is the problem?
Thanks.
Here is a sample input file:
package main
import (
"fmt"
"io/ioutil"
logger "log"
"net/http"
)
type webPage struct {
url string
body []byte
err error
}
...
And the output is basically to echo if log is imported or not.
You need to rewrite the logic of your testing function as it will only test the first line of the file. Indeed, each branch of the if [[ "$line" =~ .*log\" ]] has a break statement, so in practice, a break is reached whenever the first line is read.

Redirect mongo shell error to output

I have a script that seeds my database, but I want to only redirect the stderr to the user.
I'm trying this:
echo "Seeding pokemon"
mongo mongodb_1:27017/pokemon pokemon.js > /dev/null 2>&1
But I'm not getting the error output.If I remove the redirection, the error outputs to my console.
Mongo Shell does not currently support separate output stream for errors.
Have can subscribe to SERVER-18643 to get notified once this is implemented.
Workaround suggested in the above ticket is to tag your output inside the Mongo Shell:
...
print("<STDOUT>")
print(multiline_json)
print("</STDOUT>")
print("<STDERR>")
print(multiline_json)
print("</STDERR>")
...
Then you can redirect to the correct output stream using the following script:
#!/bin/bash
COMMAND="mongo <args>"
OUTPUT=$(${COMMAND})
function STDERR {
cat - 1>&2
}
function STDFILE {
if [ -z "$1" ]; then
return
fi
cat - >> $1
}
WRITE_ERR=0;
for line in $OUTPUT; do
if [[ "$line" == "<STDERR>"* ]]; then
WRITE_ERR=1
continue
elif [[ "$line" == "</STDERR>"* ]]; then
WRITE_ERR=0
continue
fi
if [ "$WRITE_ERR" -eq "1" ]; then
printf "%s\n" "$line" | STDERR
else
printf "%s\n" "$line"
fi
done

Expect script output at Perl console

I have a exp script -script.exp to enter a name and password. it calls test.sh file like below.
set timeout -1
spawn ./test.sh -create
match_max 100000
expect -exact "Enter the name: "
send -- "abcd\r"
expect -exact "\r
Please confirm password: "
send -- "xxy\r"
expect -exact "\r
expect eof
It gives me a output at expect window -
"Successfully entered the name"
if some issue there it throws exception or error message.
I run this expect script in a Perl file-- like below
$cmd="expect script.exp";
system($cmd);
$outputfromexp=?
I need a output of fail or passed status of exp at Perl console after running the script.
How can i do this? Please help me.
I tried calling as suggested in my Perl script--
use strict;
use warnings;
sub sysrun {
my ($command) ="expect script.exp";
my $ret_code;
$ret_code = system("$command");
if ( $ret_code == 0 ) {
# Job suceeded
$ret_code = 1;
}
else {
# Job Failed
$ret_code = 0;
}
return ($ret_code);
}
my $ret_code=sysrun();
print "reuturmsfg- $ret_code\n";
But its printing nothing-- just reuturmsfg-.
I made the changes-
my $ret_code=sysrun();
it gives me 0 and 1 return code.
If I understand the question correctly, to get the return code you want to do:
system($cmd);
my $ret_code = $?;
To get STDOUT output from the execution:
my #out = `$cmd`;
my $ret_code = $?;
I strongly suggest using strict and warnings in your code.

What would be the best logic to detect if multiple SQL options were left enabled in a config file?

I am trying to figure the best logic to determine if the user of my script has left multiple SQL option enabled in the config file the reason is only one is supported.
The first idea I had was to use a simple variable that was set to either 0,1,2,3 and then read by the script to run the correct subroutine. Then I got to thinking if they was a way to have it done by whether the section existed in the config file, it was possible with the module I am using. But the problem I ran into now is if I have it determining which SQL software to use based on the existence of a certain config section doesn't that mean I have to have logic that says if "this" section and "that" section exist then error out? But then that would mean I would to take into account all combination of all section that pertain. Right?
Was the best way to approach this the first way that I had done it? or is there a better way?
I have included samples of my config file and the unfinished subroutine which the logic would be enclosed in. I would control the existence of the sections by commenting them out in the config file. I am writing in Perl by the way and I am using Config::IniFiles for reading and writing to the INI file.
Any ideas would be very appreciated.
sub sql_option {
if (config_file()->SectionExists('SQLite')) {
sqlite_setup();
} elsif (config_file()->SectionExists('MySQL')) {
mysql_setup();
} elsif (config_file()->SectionExists('PgSQL')) {
pgsql_setup();
} elsif (config_file()->SectionExists('MSSQL')) {
mssql_setup();
} else {
print color 'red';
print "No SQL server option defined!\n";
print color 'reset';
print "\n";
die "Script halted!\n";
}
}
And the INI file:
[ESX]
host=esxi01.solignis.local
;port=
user=root
password=
[SQLite]
db=discovery.db
[MySQL]
host=sql01.solignis.local
;port=
user=root
password=
;[PgSQL]
;host=
;port=
;user=
;password=
;[MSSQL]
;host=
;port=
;user=
;password=
Here's one way of doing it:
my %sql_setup_functions = (
SQLite => \&sqlite_setup,
MySQL => \&mysql_setup,
PgSQL => \&pgsql_setup,
MSSQL => \&mssql_setup,
);
sub sql_option
{
my #engines = grep {
config_file()->SectionExists($_)
} keys %sql_setup_functions;
unless (#engines == 1) {
print color 'red';
if (#engines) {
print "Multiple SQL server options defined!\n";
print " $_\n" for sort #engines;
} else {
print "No SQL server option defined!\n";
}
print color 'reset';
print "\n";
die "Script halted!\n";
} # end unless exactly 1 SQL engine
# Call the setup function for the selected engine:
$sql_setup_functions{$engines[0]}->();
} # end sql_option