[LØST]Bash - svar fra kommando er valid

peque
Antal: 918
Tilmeldt:
20-04-2005
User is offline
[LØST]Bash - svar fra kommando er valid

Hej gruppe

Jeg har et lille script jeg gerne lige vil optimere lidt da jeg har fundet en fejl i det.
Jeg har en lokalt filnavn og et remote filnavn.
Jeg kalder den remote filnavn - via en SSH kommando som denne, hvor der er lagt ssh nøgle ind på remote host. Remote host er koblet op via VPN og derfor har nogle lange svartider/udfald ind i mellem.

RFILE=`ssh $USER@$HOST -p 222 /scripts/filename.sh`
RC=$?
if [ $RC == "" ];
then blabla
fi

Mit ønske er hvis denne return variabel er tom eller NULL - så skal jeg reagere. Men har nu set at det tager for lang tid at få dette filnavn retur, at den timer ud og det reagerer den ikke på.
skal jeg så lave den som

if [ -z "$RC" ],
then blabla
fi

Eller hvad er den bedste måde at tjekke om min variabel er tom eller NULL - eftersom det er 2filnavne der sammenlignes - men nu har jeg oplevet at scripet går videre selvom variablen mangler eller er tom.
Og kan man egenligt sætte tid på hvor længe den skal vente på dette svar via SSH

pft


frogmaster
frogmaster's picture
Antal: 3721
Tilmeldt:
20-05-2010
User is offline
kan man egenligt sætte

#0: kan man egenligt sætte tid på hvor længe den skal vente på dette svar via SSH

Det kan man godt: https://bjornjohansen.no/ssh-timeout

Det andet ved jeg squ ikke nok om og jeg har ingen mulighed for at tjekke det ud, men indtil en med mere forstand på dit spørgsmål svarer, så prøv noget i retning af:

# grep 1 /dev/null
if [[ $RC == 0 ]];

Eventuelt med elif.

Jeg bruger fx dette, for at tjekke om linux har internet eller ej iht installering. Jeg ved ikke om du kan bruge det til noget, men den burde kunne tilpasses til andet. Der er henvisninger til farve variabler du kan slette.

Internet og ekstern IP er formentlig ikke relevant, men du kan pinge den aktuelle remote maskine og på den måde få dit bash til at oplyse om status for forbindelsen.

#!/bin/bash

# Check if connected to Internet or not
ping -c 1 google.com &> /dev/null && echo -e $GREEN"Internet connected,$STD we'll attempt to install..." || echo -e $RED"Internet not accessible or an Firewall/DNS issue detected blocking PING request. You may wish to check the settings.$STD However, this might not cause problems if you get an$GREEN External IP$STD below. Please continue..."
echo

# Check External IP
externalip=$(curl -s ipecho.net/plain;echo)
echo -e $GREEN"External IP :"$STD $externalip

$SHELL


peque
Antal: 918
Tilmeldt:
20-04-2005
User is offline
#1 Tak for link - det må

#1
Tak for link - det må jeg kigge mere på.

Mit issue er som sagt de 2 filnavne - Hvor jeg har prøvet der ikke kommer svar fra dette script og dermed sættes Navn2 = ""

Jeg har fået tips herinde til hvordan jeg fik lavet mit script til - således der kunne plusses 1 til filnavnet - hvor filnavn er mysql-bin.0000XX - hvor XX er nummeret. Hvis filnavnet er tomt fra SSH kommanodoen. Så hvis ikke der er noget filnavn fra kommandoen - så ender scriptet med at tjekke om der er bevægelse i binlog filen og derefter hivs der ikke er dette - så skifter den binlog fil - Hvis den så allerede er på seneste binlogfil - så skifter den til en der ikke findes.

Så reelt er mit store problem med dette script er hvis dette return er tomt eller NULL

Ved ikke om det giver det store overblik - men det vigtige er jeg får et valid variabel tilbage fra den SSH kommando


frogmaster
frogmaster's picture
Antal: 3721
Tilmeldt:
20-05-2010
User is offline
Så reelt er mit store

#2: Så reelt er mit store problem med dette script er hvis dette return er tomt eller NULL

Denne burde virke, måske:
if [[ -a $FILE_NAME ]]; then eller i dit tilfælde formentlig:
if [[ -a $RC ]]; then

Men jeg er ikke sikker på flaget (-a).

det vigtige er jeg får et valid variabel tilbage fra den SSH kommando
Det bør være muligt at lade scriptet tjekke forbindelsen, eventuelt i intervaller (loop), før det begynder kopieringen, for på den måde at undgå der skiftes til navn2 og en binlog som ikke eksisterer.

Hvis ingen andre svarer, så stil spørgsmålet på fx https://stackoverflow.com/ https://unix.stackexchange.com eller prøv med noget i retning af dette:

Polling for existence of file on remote host
https://www.unix.com/shell-programming-and-scripti...


peque
Antal: 918
Tilmeldt:
20-04-2005
User is offline
#3 - Som en del inden jeg

#3 - Som en del inden jeg sender min SSH kommando - tjekker jeg for ping og grænsen der ligger på 5sek - hvis ikke der er svar inden da - så er forbindelsen ikke OK - Men eftersom det er VPN kan det fra Ping kommandoen og så til SSH kommandoen pludselig have lange svartider.

En anden ting - jeg skal have fundet ud af ved dette script
Jeg vil gerne hvis man når det samme sted i scriptet hvor jeg har tjekket binlogfilen bevæger.
Hvis den 5gange har fejlet med den samme fejl og binlog position - så skal den sende en mail som advarsel

Men hvordan får jeg den til at huske dette (altså at den har de seneste 5gange havnet det samme sted:

if [ $NPOS1 == $NPOS2 ];
                        then
                        echo "$DATE - $1: Sleep 15sec and testing again for $CHANNEL" >> $LOG
                        sleep 15
                        NLOGPOS3=`mysql -p$PASSWD -D$DB -e "select Master_log_pos from mysql.slave_master_info where Channel_name='$1';"`
                        NPOS3=`echo $NLOGPOS2 | rev | cut -d' ' -f 1 | rev `
                        if [ $NPOS1 == $NPOS3 ];
                        then
                                echo "$DATE - $1: No movement at all in 25sec" >> $LOG
                                echo "$DATE - $1: Stopped at $LFILE - Pos: $NPOS3" >> $LOG
                                mysql -u root -p$PASSWD -e "stop slave for channel '$CHANNEL';"
                                mysql -u root -p$PASSWD -e "start slave for channel '$CHANNEL';"
                                echo "$DATE - $1: Reload replication channel - Investigate if this error continues." >> $LOG
                                exit
                        else

Jeg ville jo gerne at der kaldes et lille script der skriver i en tmp fil - som skriver nummer af forsøg (1 - 2- 3- 4 -5) samt den binlog position.
Er det femte gang den fejler samme sted - skal den sende en mail afsted.
Men hvordan får jeg:
1. skrevet til en temp fil
2. læst fra den temp fil og verificeret hvilken gang den nu har fejlet


frogmaster
frogmaster's picture
Antal: 3721
Tilmeldt:
20-05-2010
User is offline
Men hvordan får jeg:1.

#4: Men hvordan får jeg:
1. skrevet til en temp fil
2. læst fra den temp fil og verificeret hvilken gang den nu har fejlet

Som nævnt er jeg ikke dygtig nok til bash til konkret at svare. Beklager. Du har brug for en bash geek.

Imidlertid har jeg oprettet disse to scripts, for hurtigt at få et overblik over en maskines status. Et initialiserende (./run) med kald til et andet (./system-status.sh), der blandt andet opretter 4 filer i /tmp, læser fra dem og sletter dem igen efter brug. Scriptet benytter en funktion, omgivet af { } parenteser, til oprettelsen af de midlertidige filer.

De er en del af mange andre scripts, der fungere fra en bash-menu og derfor, også af den grund, indeholder irrelevante commands iht dit spørgsmål. De vil dog fungere separat på alle Ubuntu systemer out of box (uden denne menu), fra og med Ubuntu 16.04, til og med Ubuntu 18.04, hvis de befinder sig i mapperne ~/progs/system-status

run

#! /bin/bash

# This bash call another script (system-status.sh) located within the path shown below, running the commands within that script and then return to this one.
#cd /home/administrator/progs/system-status
cd ~/progs/system-status
./system-status.sh

# Returning to this script from system-status.sh and exit the terminal
echo
tput setaf 3
tput bold
read -n1 -r -p "Press any key to exit..." key
tput sgr0
exit
# $SHELL

system-status.sh

#! /bin/bash
# When executed from the main menu, the path is: ~/progs/system-status/./run

# clear the screen
clear

# unset any variable which system may be using
unset tecreset os architecture kernelrelease internalip externalip nameserver loadaverage

while getopts iv name
do
        case $name in
          i)iopt=1;;
          v)vopt=1;;
          *)echo "Invalid arg";;
        esac
done

if [[ ! -z $iopt ]]
then
{
wd=$(pwd)
basename "$(test -L "$0" && readlink "$0" || echo "$0")" > /tmp/scriptname
scriptname=$(echo -e -n $wd/ && cat /tmp/scriptname)
su -c "cp $scriptname /usr/bin/monitor" root && echo "Congratulations! Script Installed, now run monitor Command" || echo "Installation failed"
}
fi

if [[ ! -z $vopt ]]
then
{
echo -e "Apache 2.0 License"
}
fi

if [[ $# -eq 0 ]]
then
{

# Check hardware detailed
sudo lshw # -C display
lsmod | grep radeon
lsmod | grep amd
echo

# Define Variable tecreset
GREEN='\033[32;1m'
YELLOW='\033[33;1m'
RED='\033[31;1m'
BLUE='\033[34m'
tecreset=$(tput sgr0)

# Hardware less detailed
inxi -Fxz
echo

# Check network interfaces
echo -e $YELLOW"Checking network interfaces:" $tecreset
echo -e $BLUE
netstat -ie

# Check if connected to Internet or not
ping -c 1 google.com &> /dev/null && echo -e $YELLOW"Internet     : $GREEN Connected" || echo -e $YELLOW"Internet     : $RED Disconnected"

# Check hostname
echo -e $YELLOW"Hostname     :" $tecreset $HOSTNAME

# Check Internal IP
internalip=$(hostname -I)
echo -e $YELLOW"Internal IP  :" $tecreset $internalip

# Check External IP
externalip=$(curl -s ipecho.net/plain;echo)
echo -e $YELLOW"External IP  : $tecreset "$externalip

# Check DNS
nameservers=$(cat /etc/resolv.conf | sed '1 d' | awk '{print $2}')
echo -e $YELLOW"Name Servers :" $tecreset $nameservers

# This only work on Ubuntu 16.04 and 18.04. Please uncomment according to Your need.
router=$(nmcli dev show | grep DNS | sed 's/\s\s*/\t/g' | cut -f 2)
echo -e $YELLOW"Router       :" $GREEN $router $tecreset

# This only work om Ubuntu 14.04. Please uncomment according to Your need.
# router=$(nmcli dev list | grep DNS | sed 's/\s\s*/\t/g' | cut -f 2)
# echo -e $YELLOW"Router       :" $GREEN $router $tecreset

echo -e $BLUE
netstat -r
tput sgr0
echo

# Check Logged In Users
who>/tmp/who
echo -e $YELLOW"Logged In users :" $tecreset && cat /tmp/who

# Check System Uptime
tecuptime=$(uptime | awk '{print $3,$4}' | cut -f1 -d,)
echo -e $YELLOW"System Uptime Days/(HH:MM) :" $tecreset $tecuptime

# Check Load Average
loadaverage=$(top -n 1 -b | grep "load average:" | awk '{print $10 $11 $12}')
echo -e $YELLOW"Load Average               :" $tecreset $loadaverage && echo "(the average system load per user calculated over a period of time of 1, 5 and 15 minutes)"
echo

# Check OS Type
os=$(uname -o)
echo -e $YELLOW"Operating System Type :"$tecreset $os
echo

# Check date and time for OS installation
echo -e $YELLOW'Install date:'$tecreset && sudo dumpe2fs /dev/sda1 | grep 'Filesystem created'
echo

# Check OS Release Version and Name
cat /etc/os-release | grep 'NAME\|VERSION' | grep -v 'VERSION_ID' | grep -v 'PRETTY_NAME' > /tmp/osrelease
echo -n -e $YELLOW"OS Name               :" $tecreset  && cat /tmp/osrelease | grep -v "VERSION" | cut -f2 -d\"
echo -n -e $YELLOW"OS Version            :" $tecreset && cat /tmp/osrelease | grep -v "NAME" | cut -f2 -d\"

# Check Architecture
architecture=$(uname -m)
echo -e $YELLOW"Architecture          :"$tecreset $architecture
echo

# Check Kernel Memory Space
echo -e $RED"Kernel Memory Space :" $tecreset
dmesg | grep Memory
echo

# Check Kernel Release
kernelrelease=$(uname -r)
echo -e $RED"Kernel Release      :" $tecreset $kernelrelease
echo

# Check RAM and SWAP Usages
free -h | grep -v + > /tmp/ramcache
echo -e $YELLOW"Ram Usages  :" $tecreset
cat /tmp/ramcache | grep -v "Swap"
echo -e $YELLOW"Swap Usages :" $tecreset
cat /tmp/ramcache | grep -v "Mem"
echo

# Check Disk Type, Usages and mounted volumes
df -h| grep 'Filesystem\|/dev/sda*' > /tmp/diskusage
echo -e $YELLOW"Disk type, usages and mounted volumes :" $tecreset

# Check disk rotation rate or Solid State Disk
tput setaf 2
tput bold
sudo smartctl -a /dev/sda | grep 'Rotation Rate'
tput sgr0
cat /tmp/diskusage
lsblk
echo

# Unset Variables
unset tecreset os architecture kernelrelease internalip externalip nameserver loadaverage

# Remove Temporary Files
rm /tmp/osrelease /tmp/who /tmp/ramcache /tmp/diskusage
}
fi
shift $(($OPTIND -1))

# Returning to the ./run batch to display the exit request...

Edit:
For hvad angår box brackets ( [ versus [[), så kan brugen være afgørende for funktionaliteten, især på nyere bash systemer, der ikke kræver portable kompatibilitet med POSIX, som jeg tror er forældet. Single box brackets virker dog fortsat, men har færre muligheder.

For hurtigt at teste forskellen, så skriv i terminalen henholdvis [ og tryk Enter (der i sig selv er en command) og derefter [[ (der venter på yderligere input).


peque
Antal: 918
Tilmeldt:
20-04-2005
User is offline
#5 - Super - tak for info -

#5 - Super - tak for info - så fik jeg kmit lille scripts til at skrive til extern fil.

Så det eneste jeg mangler nu - er at finde ud af min SSH kommando ikke kommer tom hjem


frogmaster
frogmaster's picture
Antal: 3721
Tilmeldt:
20-05-2010
User is offline
Glimrende.Selve det at

Glimrende.

Selve det at oprette en tekstfil, skrive til den og vise indholdet, alt sammen fra terminalen, er grundlæggende ganske enkelt:

Opretter en tom tekstfil:
> test.txt

Skriver til filen:
echo "skriv noget tekst" > test.txt

Viser indholdet:
cat test.txt

#6: Så det eneste jeg mangler nu - er at finde ud af min SSH kommando ikke kommer tom hjem

Jeg vil tro at dette fungerer, med de nødvendige tilpasninger (kopiering), eventuelt sammen med client SSH timeout prevention: ServerAliveInterval 120 (af hensyn til lange svartider angående VPN) i ~/.ssh/config og initialiserende ping.

#!/bin/bash

while true
do
  ssh user@IP-adresse 'ls /path/to/remote/file' > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
      echo "Connection OK and file is found"
# echo "Begin copying ..."
# ssh user@IP-adresse 'cd /path/to/remote/file' osv ...
      exit
  else
     echo "Connection not accessible or file not found. Trying again in 10 secs ..."
     sleep 10;
  fi
done

$SHELL

--------

#!/bin/bash

GREEN='\033[32;1m'
YELLOW='\033[33;1m'
RED='\033[31;1m'
STD='\033[0m'

# Ping IP
echo
echo -e $YELLOW"Ping server..."$STD
echo

PING_1()
{
  ping -c 1 $1 > /dev/null
  [ $? -eq 0 ] && echo -e Node:$GREEN $i$STD is up.
}

# Change the IP address here
for i in IP-address
do PING_1 $i & disown
tput sgr0
done
$SHELL

Hvis den 5gange har fejlet med den samme fejl og binlog position - så skal den sende en mail som advarsel

Der er mange måder at sende mails på fra terminalen. Håber dette kan være til inspiration: https://blog.edmdesigner.com/send-email-from-linux...


peque
Antal: 918
Tilmeldt:
20-04-2005
User is offline
Jamen løsningen er som så

Jamen løsningen er som så :-)

RFILE=`ssh $USER@$HOST -p 222 /scripts/filename.sh`
if [ "$RFILE" == "" ];
               then
                       echo "$DATE - $1: Could not get Remote Binlog File name - exiting" >> $LOG
                        exit
                fi

Hvilket giver mig ved tomt filnavn:
2018-09-06 07:30:23 - Vesselname: Could not get Remote Binlog File name - exiting

Så nu skulle alle mine problemer være løst.
Selve mit mail afsendelse er ikke et problem - Kun omkring tilladelse til at gøre dette -. Men det er rederiet der skal afgøre dette