How to save response from telnet script? - linux

I've got my script going as far as It can connect, login and run the command. But I'm stuck as how do I save the response from the command to a file, without saving the whole session.
#!/bin/sh
Var=1
while [ $Var -lt 20 ]
do
HOST='IPa.ddr.ess.'$Var
USER='MyUser'
PASSWD='MyPassword'
CMD='MyCommand'
(
echo open "$HOST"
sleep 1
echo "$USER"
sleep 1
echo "$PASSWD"
sleep 1
echo "$CMD"
#I want to save the output from my $cmd to an varaible $Output
#Then I want to write "$HOST - $Output" to a file named "output.txt"
sleep 2
echo "exit"
) | telnet
Var=$((Var + 1))
done
I'd appreciate any help, or pointers in the right direction

Ok, this looks more challenging than I initially thought. I like it :-)
#!/bin/sh
Var=1
while [ $Var -lt 20 ]
do
HOST='IPa.ddr.ess.'$Var
USER='MyUser'
PASSWD='MyPassword'
CMD='MyCommand'
MARKER='XXXX1234:AUIE'
(echo "$HOST - " ; (
echo unset echo
echo open "$HOST"
sleep 1
echo "$USER"
sleep 1
echo "$PASSWD"
sleep 1
echo echo "$MARKER"
echo "$CMD"
#I want to save the output from my $cmd to an varaible $Output
#Then I want to write "$HOST - $Output" to a file named "output.txt"
sleep 2
echo "exit"
) | telnet | sed -e "1,/$MARKER/d" ) >> output.txt
Var=$((Var + 1))
done
What this does is:
it disables echo-ing in telnet
After the login session, it prints a marker
anything after the marker is saved into output.txt
I imbricated into yet another shell that will print the "$HOST -" part

Related

Terminal Freezing after Bash Script Succeeded

I have a pretty simple bash script that coordinates running a couple python scripts. What I am having trouble figuring out is why after running the bash script (. bash_script.sh), the terminal hangs. I can't ctrl+c, ctrl+z or do anything except restart the SSH session. All I see is just a blinking cursor. Checking all the log files indicates a 0 status exit code with no errors in the scripts themselves. Running ps aux | grep bash_script.sh does not show any anything running either. Is there anyway to debug this?
#!/bin/bash
exec >> <DIR>/logfile.log 2>&1
script_message () {
status_arg=$1
if [[ $status_arg = "pass" ]]; then
printf "Script Done\n"
printf '=%.0s' {1..50}
printf "\n"
elif [[ $status_arg = "fail" ]]; then
printf "Script Failed\n"
printf '=%.0s' {1..50}
printf "\n"
else
:
fi
}
current_date=$(date '+%Y-%m-%d %H:%M:%S')
day=$(date +%u)
hour=$(date +%H)
printf "RUN DATE: $current_date\n"
# activate virtual env
source /<VENV DIR/bin/activate>
python <PYTHON SCRIPT>.py >> <DIR>/logfile2.log 2>&1
retVal=$?
if [[ $retVal -eq 0 && $day -eq 4 ]]; then
python <PYTHON SCRIPT 2>.py >> <DIR>/logfile3.log 2>&1
script_message pass
elif [[ $retVal -eq 0 ]]; then
script_message pass
else
#:
script_message fail
fi
echo $?

Bash get last line (combined) from stdout

I have a script that performs many different operations and displays the status of their completion in a clear way for the user. I need a function so that some strings can be retrieved as variables for further processing.
This is a highly simplified example:
#!/bin/bash
echo "Test script."
echo -n "1) cat file "
cat ./testfile.f &> /dev/null
if [ $? -eq 0 ]
then
echo "$(tput hpa $(tput cols))$(tput cub 8)[OK]"
else
echo "$(tput hpa $(tput cols))$(tput cub 8)[FAIL]"
fi
echo -n "2) make subfolder "
mkdir ./testdir &> /dev/null
if [ $? -eq 0 ]
then
echo "$(tput hpa $(tput cols))$(tput cub 8)[OK]"
else
echo "$(tput hpa $(tput cols))$(tput cub 8)[FAIL]"
fi
It take some as:
$./test.sh
Test script.
1) cat file [FAIL]
2) make subfolder [OK]
How can I get the last line (ideally, any string) during script execution? Ideally it would be using a function (so I could work with the resulting string) This string will be processed in the same script.
So far, I see only one solution: redirect the output of each echo command using tee.
Is there any way to read the already outputted data!?
Suppose that you have strings {1..5} that you need to process:
process() {
while read -r input; do
sleep 2
echo "Processed ${input}."
done
}
printf "line %s\n" {1..5} | process
In this situation you might want to see the numbers before they are being processed.
You can do this by duplicating stdout to fd 3 and use a function.
display() {
while read -r input; do
echo "=== ${input} ===" >&3
echo "${input}"
done
}
process() {
while read -r input; do
sleep 2
echo "Processed ${input}."
done
}
exec 3>&1
printf "line %s\n" {1..5} | display | process

file check 3 times and exit shell script

I want to check for file in directory if there then push it to ssh server checing server connection if file not there then try 3 times with each 1min interval and in between if it comes ( on 2nd attend for example) then try again to connect ssh and push. else check for 3 attempts and exit
Please check my below code it is halting after 1st attempt ( during 2nd attempt I am making file available)
#!/bin/sh
echo "OK, start pushing the Userdetails to COUPA now..."
cd /usr/App/ss/outbound/usrdtl/
n=0
until [ $n -ge 3 ] || [ ! -f /usr/App/ss/outbound/usrdtl/USERS_APPROVERS_*.csv ]
do
if [ -f /usr/App/ss/outbound/usrdtl/USERS_APPROVERS_*.csv ] ;
then
pushFiles()
else
n=$[$n+1]
sleep 60
echo " trying " $n "times "
fi
done
pushFiles()
{
echo "File present Now try SSH connection"
while [ $? -eq 0 ];
do
echo $(date);
scpg3 -v /usr/App/ss/outbound/usrdtl/USERS_APPROVERS_*.csv <sshHost>:/Incoming/Users/
if [ $? -eq 0 ]; then
echo "Successfull"
echo $(date);
echo "Successfull" >> /usr/App/ss/UserApproverDetails.log
exit 1;
else
echo $(date);
echo "Failed" >> /usr/App/ss/UserApproverDetails.log
echo "trying again to push file.."
scpg3 -v /usr/App/sg/outbound/usrdtl/USERS_APPROVERS_*.csv <ssh Host>:/Incoming/Users/
echo $(date);
exit 1;
fi
done
}
I've tried to simplify this code for you. I hope it helps:
#!/bin/bash
outdir="/usr/App/ss/outbound/usrdtl"
logfile="/usr/App/ss/UserApproverDetails.log"
file_prefix="USERS_APPROVERS_"
function push_files() {
echo "File present now try SSH connection"
local attempts=1
local retries=2
date
while [[ ${attempts} -lt ${retries} ]]; do
if scp ${outdir}/${file_prefix}*.csv <sshHost>:/Incoming/Users/ ; then
echo "Successful" | tee -a ${logfile}
date
exit 0
else
echo "Failed" >> ${logfile}
fi
attempts=$((attempts+1))
do
echo "scp failed twice" | tee -a ${logfile}
exit 2
}
echo "OK, start pushing the Userdetails to COUPA now..."
cd ${outdir}
attempts=1
retries=3
while [[ ${attempts} -lt ${retries} ]]; do
echo "looking for files...attempt ${attempts}"
if test -n "$(shopt -s nullglob; echo ${outdir}/${file_prefix}*.csv)"; then
push_files()
fi
attempts=$((attempts+1))
sleep 60
done
echo "Files were never found" | tee -a ${logfile}
exit 1
Look at this code and tell me how it's not doing what you're trying to do. The most complicated part here is the nullglob stuff, which is a handy trick to see if any file in a glob matches
Also, I generally used bashisms.

How to use shell variables after doing sudo su

I am writing a script to fix a missing 'F' letter in a mail log file. The mail log file is continuously updating. I am getting a file name, after that I am doing 'sudo su' to get superuser access. Inside sudo, I am fixing a that missing 'F'. However, I am unable to use that file name inside sudo block. Please can anyone help me how I can export these shell variables inside sudo? I tried using export but its not working. the code block I have created is as follows-
#Script to solve F issue
#----------------------------------------
#By Kapil Shirsath
#----------------------------------------
cd /var/spool/mail #mail files reside in mail folder
echo "Entered in mail folder"
filename=`ls -lrt 99999*| sort -k 5 -rn | head -1 | tr -s " " "," | cut -d "," -f "8"` # this will list the file with maximum size`
echo "File with maximum size is $filename"
echo "----------------------------------------------------"
echo "Is it the file expected?(y/n)"
read choice
if test $choice == "n"
then
echo "Exiting...."
exit;
fi;
c=1
while [ $c -le 5 ]
do
ls -lrt $filename
echo $filename
sleep 3
c=`expr $c + 1`
done
echo "---------------------------------------------------"
sudo su<<'HERE' #this will give you super user permissions
echo "Got root access"
echo "First line of the file is as below :"
head -1 $filename
echo "---------------------------------------"
firstline=`head -1 $filename`
echo "Repeat : $firstline"
echo $firstline | grep ^"rom" >/dev/null
if test $? -eq 0
then
ex -s $filename <<'EOF'
1s/^/F/
:wq
EOF
echo "F issue fixed!"
HERE
c=1
while [ $c -le 5 ]
do
ls -lrt $filename
sleep 3
c=`expr $c + 1`
done
echo "---------------------------------------------------"
else
echo "Not finding the missing 'F' ! !! Kindly check with your system "
exit;
fi;

BASH If [[ "$a" == *"$b"* ]] Always true even when it shouldn't be

I am trying to write a small bash script to monitor the output of RiotShield (a 3rd party player scraper for League of Legends) for crashes. If a keyword is found in the log it should kill the process and restart it.
Here is my bash script as is:
#!/bin/bash
crash[1]="disconnected"
crash[2]="38290209"
while true; do
list=$(tail log.log)
#clear
echo "Reading Log"
echo "========================================"
echo $list
for item in ${list//\\n/ }
do
for index in 1 2
do
c=${crash[index]}
#echo "Crash Word:" $c
if [[ "$c" == *"$item"* ]]; then
echo "RiotShield has crashed."
echo "Killing RiotShield."
kill $(ps aux | grep '[R]iotShield.exe' | awk '{print $2}')
echo "RiotShield killed!"
echo "Clearing log."
echo > log.log
echo "Starting RiotShield"
(mono RiotShield.exe >> log.log &)
fi
done
done
sleep 10
done
My crash array are keywords that I know show in the log when it crashes. I have 38290209 in there only for testing purposes as it is my summoner ID on League of Legends and the moment I preform a search for my Summoner name the ID shows in the log.
The problem is even when disconnected and 38290209 do not show up in the log my
if [[ "$c" == *"$item"* ]]; then
fires, kills the RiotShield process and then relaunches it.
The length of the crash array will grow as I find more keywords for crashes so I cant just do
if [[ "$c" == "*disconnected*" ]]; then
Please and thanks SOF
EDIT:
Adding working code:
#!/bin/bash
crash[1]="disconnected"
crash[2]="error"
while true; do
list=$(tail log.log)
clear
echo "Reading Log"
echo "========================================"
echo $list
for index in 1 2
do
c=${crash[index]}
#echo "Crash Word:" $c
if [[ $list == *$c* ]]; then
echo "RiotShield has crashed."
echo "Crash Flag: " $c
echo "Killing RiotShield."
kill $(ps aux | grep '[R]iotShield.exe' | awk '{print $2}')
echo "RiotShield killed!"
echo "Clearing log."
echo > log.log
echo "Starting RiotShield"
(mono RiotShield.exe >> log.log &)
fi
done
sleep 10
done
I think you have the operands in your expression the wrong way around. It should be:
if [[ $item == *$c* ]]; then
because you want to see if a keyword ($c) is present in the line ($item).
Also, I'm not sure why you need to break the line into items by doing this: ${list//\\n/ }. You can just match the whole line.
Also note that double-quotes are not required within [[.

Resources