Log output from bash script into log file and stdout while running from perl - linux

I have perl script
perl script (install.pl):
use strict; use warnings;
use Term::ANSIColor;
my $logfilename = "install.log";
open LOG,">$logfilename" or die "failed to open log file reason:$!";
sub logMsg
{
my ($msg) = #_;
my ($error) = $_[1];
$msg .= "\n";
print LOG $msg;
if( $error ) { print color 'red' ;}
{print $msg}
if( $error ) { print color 'reset' ;}
}
sub lampInstall
{
logMsg("Installing apache2, php, and mysql db");
# Install apache2 and mysql:
my $cmdOutput = `./ubuntu-lamp-install.sh`;
print LOG "$cmdOutput\n";
}
lampInstall();
close LOG;
bash script (ubuntu-lamp-install.sh)
#!/bin/bash
sudo apt-get update
sudo apt-get install ntp
sudo /etc/init.d/ntp start
export DEBIAN_FRONTEND=noninteractive
echo "mysql-server mysql-server/root_password password test" | sudo debconf-set-selections
echo "mysql-server mysql-server/root_password_again password test" | sudo debconf-set-selections
sudo apt-get install -y apache2 php5 libapache2-mod-php5
sudo service apache2 restart
sudo a2enmod ssl
The issues is that , when install.pl is invoked, it waits for long time and does not give any output information of what is being installed.I need it to change the perl script to display the output information from bash script(better if instantaneous) as well as log the output to log file. The script is written by someone else , I have very little knowledge of perl scripting.

You could do something like
open my $cmdOutut, "-|", "./ubuntu-lamp-install.sh";
while (<$cmdOutput>) {
print LOG "$_\n";
print "$_\n";
}
in your lampInstall().
This is the new lampInstall():
sub lampInstall
{
logMsg("Installing apache2, php, and mysql db");
# Install apache2 and mysql:
open my $cmdOutut, "-|", "./ubuntu-lamp-install.sh";
while (<$cmdOutput>) {
print LOG "$_\n";
print "$_\n";
}
}

Related

PowerShell script to SSH to Multiple Linux devices and restart/reboot them

I am comfortable with writing single queries. I am new to writing bash scripts trying to automate the daily stuff. I need help on creating a PowerShell or bash script where I can SSH to multiple Linux devices with same SSH key and then reboot the devices.
I access linux devices manually with the following command in PowerShell
ssh -i C:\<path-to-the-private-key\test.ppk test#XX.X.X.XXX (X - IP Address)
Then I enter the following command
sudo reboot
It asks me to type the password and then restarts the device.
I have 100+ devices that I need to restart.
I can get a list of all IP address in a text file. How can we search for all the IP address in a text file, authenticate with the SSH private key and run the sudo command to restart the device?
Would it also be possible to throw a message if it was not able to restart a device?
Any help would be appreciated.
This is the script that I have.
testreboot.sh
#!/bin/bash
pw="test123"
hosts='IP.txt'
while read -r line; do {
/usr/bin/expect << EOF do
ssh test#"$hosts" 'sudo reboot'
expect "*?assword*"
send "%pw\r"
EOF
}
done < $hosts
IP.txt
XXX.XX.XX.XX
XXX.XX.XX.XX
XXX.XX.XX.XX
XXX.XX.XX.XX
I have Ubuntu 20.04 installed from Windows App Store. I am trying to run the testreboot.sh from PowerShell using the following command and get the following error message.
bash testreboot.sh
testreboot.sh: line 2: $'\r': command not found
testreboot.sh: line 3: $'\r': command not found
testreboot.sh: line 5: $'\r': command not found
testreboot.sh: line 16: syntax error near unexpected token `done'
testreboot.sh: line 16: `done < $hosts'
A better solution to this problem is to use something like Ansible, Chef, or Puppet to solve these multi-server coordination needs.
Here is an example in a shell script using expect to ssh to another server and login:
NOTE: When you use expect in this manner, you need to escape " and $ and
other items. If password has $, it must be escaped.
This is where after logging in and expect see a command prompt
For example:
44 [localhost.localdomain]/home/map%
This is where you would need to add sudo reboot command
-re \"$reg_ex_prompt\" {
}
Test Script:
#!/bin/sh
#
debug=0
exit_val=0
spawn_item="ssh"
destination="user_name#<IP of server to shh>"
reg_ex_prompt='\[%|>|\$|#\] $'
#
# Change -D 0 to -D 1 to debug interactivly
#
expect -D $debug -c "
spawn $spawn_item $destination
set ret 1
set timeout 20
expect {
timeout {
send_user \"Timeout reached!\"
exit \$ret
}
eof {
puts \"End of test connection reached!\"
if { \$ret == 0 } {
puts \"Connection test Successful!\"
puts \"Exiting $destination ...\"
} else {
puts \"Connection Failure!\"
}
exit \$ret
}
\"Connection refused\" {
puts \"ERROR: Trouble connecting to $device_type_parm destination $destination\"
puts \"Aborting...\"
exit \$ret
}
\"Permission denied\" {
puts \"ERROR: User name or password is incorrect for $destination\"
puts \"Aborting...\"
exit \$ret
}
\"Connection reset by peer\" {
puts \"ERROR: Trouble connecting to $destination\"
puts \"Aborting...\"
exit \$ret
}
\"you sure you want to continue connecting\" {
send \"yes\r\"
exp_continue
}
\"assword:\" {
puts \"\r\nSending password\"
send \"password\\\$\r\"
exp_continue
}
\"Choice? \" {
send \"1\r\"
exp_continue
}
\"Q. Quit\" {
send \"q\r\"
exp_continue
}
-re \"$reg_ex_prompt\" {
send \"sudo reboot\r\"
sleep 2
set ret 0
exit \$ret
}
interact
} "
# get the exit value from expect statment above
exit_val=$?

Unable to access local variable via a function call through ssh

This the code I,m trying to execute:
#!/bin/bash
set -e -a
err_report() {
echo "Error on line $1"
}
trap 'err_report $LINENO' ERR
IFS=$'\n'
value=($(cat builds.txt))
prevBuild=${value[0]}
prevBuildDir=$prevBuild
currentBuild=${value[1]}
currentBuildDir=$currentBuild
splitPrevBuild=(${prevBuild//./$'\n'})
splitcurrentBuild=(${currentBuild//./$'\n'})
prevBuildSR=${splitPrevBuild[2]}
prevBuildHF=${splitPrevBuild[3]}
prevBuildNum=${splitPrevBuild[4]}
currentBuildSR=${splitcurrentBuild[2]}
currentBuildHF=${splitcurrentBuild[3]}
currentBuildNum=${splitcurrentBuild[4]}
function change {
cd ~/InstallationFiles/${currentBuildSR}/${currentBuildDir}/${currentBuild}extracted
}
change
pwd
ssh -T atao52#kvs-in-hsglap17.in.kronos.com <<-EOF
$(typeset -f)
change
pwd
echo hi
exit
EOF
How to access the variables as currently, it says
cd: /home/atao52/InstallationFiles///extracted: No such file or directory

nodejs give unwanted message while running shell script in linux

try to execute shell script using nodejs and nodejs server gives wrong error message
shell script
sudo mkdir updateinprogress
servicebranch="Development"
currentpath="$PWD"
tarfilename="$(date +'%d-%m-%Y_%H-%M-%S')"
cd ..
if [ ! -d "backups" ]; then
sudo mkdir backups
fi
cd backups
if [ ! -d "AppInEngine" ]; then
sudo mkdir AppInEngine
fi
cd $currentpath
if [ ! -d "current_file_backup" ]; then
sudo mkdir current_file_backup
fi
sudo cp -r /var/www/AppInEngine $currentpath/current_file_backup/
sudo git clone https://github.com/abc/AppInEngine --branch $servicebranch -q
if [ $? != 0 ]; then
echo -e "{\"status\":\"false\", \"message\":\""error occerd while cloning git repository "\"}"
sudo rm -r AppInEngine updateinprogress current_file_backup
exit
fi
sudo cp -r /var/www/AppInEngine/configs AppInEngine
sudo cp -r /var/www/AppInEngine/Logs AppInEngine/
sudo rm -r /var/www/AppInEngine
sudo cp -r AppInEngine /var/www
sudo chmod -R 777 /var/www/AppInEngine
service apache2 restart > /dev/null
if [ $? != 0 ]; then
sudo rm -r /var/www/AppInEngine
sudo cp -r $currentpath/current_file_backup/AppInEngine /var/www/
sudo service apache2 restart > /dev/null
sudo rm -r AppInEngine updateinprogress current_file_backup
echo -e "{\"status\":\"false\", \"message\":\""error occerd while starting apache2 .restart with backup "\"}"
exit
fi
sleep 160
if curl -s --head --request GET http://localhost/AppInEngine/get_version | grep "200 OK" > /dev/null; then
sudo tar -cf AppInEngine_$tarfilename.tar.gz current_file_backup/AppInEngine
sudo mv AppInEngine_$tarfilename.tar.gz ../backups/AppInEngine/
cd ../backups/AppInEngine
#sudo cp AppInEngine$tarfilename.tar.gz
sudo rm -f $(ls -1t | tail -n +3)
cd $currentpath
sudo rm -r AppInEngine updateinprogress current_file_backup
echo -e "{\"status\":\"true\", \"message\":\""service update success"\"}"
exit
else
echo -e "{\"status\":\"false\", \"message\":\""service update faild .trying to start with backup "\"}"
sudo service apache2 stop
sudo rm -r /var/www/AppInEngine
sudo cp -r $currentpath/current_file_backup/AppInEngine /var/www/
sudo rm -r AppInEngine ls current_file_backup
chmod -R 777 /var/www/AppInEngine
sudo service apache2 start > /dev/null
exit
fi
nodejs server
var express = require('express');
var app = express();
var exec = require('child_process').exec, child;
app.listen(4105);
app.get('/updateEngin',function (req, res){
var testscript = exec('sh test.sh /var/www/update/serviceupdate');
testscript.stdout.on('data', function(data){
console.log(data);
res.json(data);
});
});
output when running script alone in terminal (./test.sh )
{"status":"true", "message":"service update success"}
ouput when running using nodejs
{"status":"false", "message":"error occerd while cloning git repository "}
{"status":"true", "message":"service update success"}
set time out to nodejs server
issue will fixed
var express = require('express');
var app = express();
var timeout = require('connect-timeout');
var exec = require('child_process').exec, child;
app.listen(4105);
app.get('/updateEngin', timeout('160s'), function (req, res){
var testscript = exec('sh test.sh /var/www/update/serviceupdate');
testscript.stdout.on('data', function(data){
console.log(data);
res.json(data);
});
});

Zip file is not extracting by crontab

i am using a perl script for unzipping a zip file by crontab. The script is working properly if i execute it manually. but whenever i set it in cron the script does not work any more. i have tested cron setting other script files are working from cron only this zip extracting script is not working .
Script is as follows :
#!/usr/bin/perl
use IO::Uncompress::Unzip qw(unzip $UnzipError);
$dir = '/root/perl';
open (han2, "ls -l $dir/*.zip |awk '{print \$9}'|");
#array1 = <han2>;
chomp(#array1);
for ($i=0;$i<=$#array1;$i++) {
$zipfile = $array1[$i];
$u = new IO::Uncompress::Unzip $zipfile
or die "Cannot open $zipfile: $UnzipError";
die "Zipfile has no members"
if ! defined $u->getHeaderInfo;
for ( $status = 1; $status > 0; $status = $u->nextStream) {
$name = $u->getHeaderInfo->{Name};
warn "Processing member $name\n" ;
if ($name =~ /\/$/) {
mkdir $name;
}
else {
unzip $zipfile => $name, Name => $name
or die "unzip failed: $UnzipError\n";
}
}
}
Crontab setting :
34 14 * * * /root/perl/./unzip.pl > /dev/null 2>&1
Please help me to do this task by cronjob
When cron executes your script, the current directoy probably won't /root/perl. Try chdir($dir) after you set $dir, or use full pathnames where required:
$u = new IO::Uncompress::Unzip "$dir/$zipfile"
or die "Cannot open $zipfile: $UnzipError";
mkdir "$dir/$name";
unzip "$dir/$zipfile" => "$dir/$name" ...
Changing to the correct directory is probably easier.

Why isn't stdout set after executing a child process in a node.js script that's running as a daemon?

This works as expected if I run it from the command line (node index.js). But when I execute this Node.js (v0.10.4) script as a daemon from a init.d script the stdout return value in the exec callback is not set. How do I fix this?
node.js script:
var exec = require('child_process').exec;
setInterval(function()
{
exec('get_switch_state', function(err, stdout, stderr)
{
if(stdout == "on")
{
// Do something.
}
});
}, 5000);
init.d script:
#!/bin/bash
NODE=/development/nvm/v0.10.4/bin/node
SERVER_JS_FILE=/home/blahname/app/index.js
USER=root
OUT=/home/pi/nodejs.log
case "$1" in
start)
echo "starting node: $NODE $SERVER_JS_FILE"
sudo -u $USER $NODE $SERVER_JS_FILE > $OUT 2>$OUT &
;;
stop)
killall $NODE
;;
*)
echo "usage: $0 (start|stop)"
esac
exit 0
I ended up not using Node.js exec child_process. I modified the init.d script above (/etc/init.d/node-app.sh) as follows:
#!/bin/bash
NODE=/home/pi/development/nvm/v0.10.4/bin/node
SERVER_JS_FILE=/home/pi/development/mysql_test/index.js
USER=pi
OUT=/home/pi/development/mysql_test/nodejs.log
case "$1" in
start)
echo "starting node: $NODE $SERVER_JS_FILE"
sudo -u $USER TZ='PST' $NODE $SERVER_JS_FILE > $OUT 2>$OUT &
;;
stop)
killall $NODE
;;
*)
echo "usage: $0 (start|stop)"
esac
exit 0
This script launches the Node.js app "index.js" at boot up and everthing works as expected.

Resources