Bash script help

Sziasztok!

A következő a tervem: van pár nyomtatónk, amiknek a számlálóit le kellene kérdezni snmp-vel, majd bizonyos időközönként elküldeni e-mailben. (Lenne hozzá gyári program, de semmit nem ér.)
Van egy Observium, ami jól teszi a dolgát, csak jelentést nem tud küldeni.
Addig eljutottam, hogy *mindent is* tudok küldeni a sendmail segítségével.
Kellene egy viszonylag rendezett kimenettel rendelkező script, aminek az eredményét át tudom irányítani a sendmail felé.
A lényege annyi, hogy van egy adatok nevű fájl, amiből soronként kiolvassa az ip címeket és szépen lekérdezi. Jó lenne, ha ezt meg lehetne toldani mondjuk soronként egy TAB után az eszközök nevével is (Pistike, Jancsika, stb..) de erre még nem jöttem rá hogyan lehetne, így egyelőre csak annyi van, hogy kiírja az ip címet és mellé a számláló állását.
Szóval eddig ez van:


#!/bin/bash
UDVOZLO="Nyomtato szamlalok lekerdezese..."
HIBA="-----=====##### HIBA! #####=====-----"
HADAT="Az adatok fájl nem található"

echo $UDVOZLO

if test -f "adatok"; then
for i in `seq $(cat adatok | wc -)`; do
sor=`head -n$i adatok | tail -1`
echo $sor | tr -d '\r \n'
eredmeny=`snmpget -v2c cname $sor -Ov iso.3.6.1.2.1.43.10.2.1.4.1.1`
szamlalo=`echo $eredmeny | awk '{print " :" $2}'`
eredmenyf=`echo $eredmeny | awk '{print $1}'`
if [ eredmenyf = "Timeout:" ]; then
echo "Kikapcsolva"
else
echo $szamlalo
fi
done
else
echo $HIBA
echo $HADAT
fi

Vázlatosan annyit csinál, hogy soronként kiolvassa az "adatok" fájl tartalmát (IP címek), amiket elkezd lekérdezni.
Az érdekes rész az eredmenyf nevű változónál van. Ha válaszol az eszköz, akkor ilyen eredményt ad az snmp:
Counter32: 72176

Ha nem válaszol, mert hibás a cím vagy ki van kapcsolva, stb... akkor:
Timeout: No response from 1.2.3.4.

Szerettem volna kivágni awk-val az első szót, amit a következő if-el megvizsgálok. Ha ez "Timeout:", akkor kiírja, hogy kikapcsolva.
Amíg van válasz, addig ez jól is működik, viszont ha jön a Timeoutos eredmény, akkor az awk valami miatt nem kezeli (próbáltam konzolon is csak egy sort), hanem visszaadja az egész sort.
Hogyan lehetne ezt kezelni?

Hozzászólások

mi az "echo $?" eredménye timeout esetén? esetleg vizsgálhatnál arra, ha nem 0 értéket ad vissza.

Jelenleg így néz ki a dolog:

#!/bin/bash
#Nyomtato szamlalok lekerdezese
UDVOZLO="Nyomtato szamlalok lekerdezese..."
HIBA="-----=====##### HIBA! #####=====-----"
HADAT="Az adatok fajl nem talalhato!"

echo $UDVOZLO

if test -f "adatok"; then
for i in `seq $(cat adatok | wc -l)`; do
<------>sor=`head -n$i adatok | tail -1`
<------>echo $sor | tr -d '\r \n'
<------>eredmeny=`snmpget -v2c -c public -m SNMPv2-MIB -M /opt/observium/mibs/rfc $sor -Ov iso.3.6.1.2.1.43.10.2.1.4.1.1`
<------>szamlalo=`echo $eredmeny | awk '{print ": " $2}'`
<------>if [ 'echo $?' = "1" ]; then
<------> echo ": Kikapcsolva"
<------>else
<------> echo $szamlalo
<------>fi
done
else
echo $HIBA
echo $HADAT
fi

Sajnos ugyanolyan hülye a kimenet (az utolsó ip direkt hibás):

adam@gepezet~# ./test.sh
Nyomtato szamlalok lekerdezese...
10.61.4.30: 93624
10.61.4.20: 116766
10.61.4.51: 260634
10.61.5.50Timeout: No Response from 10.61.5.50.
:

---
- Indítsd újra a gépet! - Az egészet? - Nem, a felét...

És hol az átirányítás?

Ez van, amikor a bufferelt soroba érkezik egy nem bufferelt sor.

$? Expands to the exit status of the most recently executed foreground pipeline.
Forrás: Bash Reference Manual
3.4.2 Special Parameters

exit status: Unix alatt 0 a hibátlan futás, >0 a hibás.
Sajnos a fostalicska linux man-ja nem említ ilyen apróságokat. ;)

No akkor javaslom besétálni egy antikváriumba, és beszerezni,majd pedig átolvasni az örökbecsű K&P könyvet (első lecke: utánanézni, hogy ez pontosan melyik könyv), mert ez már a második olyan kérdés, ami azt jelzi, hogy alapvető ismeretek hiányoznak. A $? egyébként az utolsó visszatérési érték, amit ha el akarsz rakni saját változóba, akkor elég annyit mondani, hogy: foo=$?

Próbáld meg így:

snmpget -v2c cname $sor -Ov iso.3.6.1.2.1.43.10.2.1.4.1.1 2>&1

Ezt már láttam máshol is, de nem tudom mit jelent ez a >&1

Egyébként ugyanaz, sed-el is próbáltam így:

teszt=`snmpget -v2c cname $sor -Ov iso.3.6.1.2.1.43.10.2.1.4.1.1 2>&1 | sed 's/Timeout: No Response */Kikapcsolva/'`
A teszt változóba gyönyörűen belerakja az snmpget eredményét, viszont ha hibát ír, akkor a változó üres.

---
- Indítsd újra a gépet! - Az egészet? - Nem, a felét...

Ez azért van, mert unix alatt a programok az stdout-ra írnak.
A hibát meg bufferelés nélkül a stderr-re.
0 = stdin
1 = stdout
2 = stderr
A

2>&1

azt jelenti, hogy az stderr-t átirányítja az stdout-ra.

Ettől kezdve az sed, awk, stb - amik az stdin-t olvassák, be tudják olvasni az stdout-ra és stderr-re érkező sorokat is.

(Unix gyenge kezdő tankönyv vége.)

/off: én biztosan nem szivatnám magam ennél a feladatnál shell scripttel. Pythonhoz és nodejs-hez is van snmp csomag, meg mailsender is, tehát a lekérdezés ugyan úgy pár sor, viszont sokkal egyszerűbb a hibaeseteket kezelni, mint pl. bashben.

/on: hogy konstruktív is legyek, valóban a $? értékét érdemes vizsgálni az snmpget-es sor után, mert abból meg tudod mondani, hogy az snmpget milyen kóddal tért vissza és ebből eldönteni, hogy érdemes-e awk-val bármit vagdosni, vagy error volt

Ez most működik (igaz, hogy telef..ssa a képernyőt ha hiba van, de a fájlba pont azt írja, amit szeretnék).
Még annyi tippet kérnék esetleg ha van ötletetek, hogy hogyan lehetne az ip címek mellé nevet is írni.
Majd ezek után elküldöm a fájl tartalmát e-mailben de az már menni fog :)


#!/bin/bash
#Nyomtato szamlalok lekerdezese

declare -i hiba

UDVOZLO="Nyomtato szamlalok lekerdezese..."
HIBA="-----=====##### HIBA! #####=====-----"
HADAT="Az adatok fajl nem talalhato!"

echo $UDVOZLO
echo $UDVOZLO > proba

if test -f "adatok"; then
for i in `seq $(cat adatok | wc -l)`; do
<------>sor=`head -n$i adatok | tail -1`
<------>echo $sor | tr -d '\r \n'
<------>`echo $sor | tr -d '\r \n'>>proba`
<------>eredmeny=`snmpget -v2c -c public -m SNMPv2-MIB -M /opt/observium/mibs/rfc $sor -Ov iso.3.6.1.2.1.43.10.2.1.4.1.1 >&1`
<------>hiba=`echo $?`
<------>szamlalo=`echo $eredmeny | awk '{print ": " $2}'`
<------>if [ $hiba -gt 0 ]; then
<------> szamlalo=": Kikapcsolva"
<------> echo $szamlalo
<------> echo $szamlalo>>proba
<------>else
<------> echo $szamlalo
<------> echo $szamlalo>>proba
<------>fi
done
else
echo $HIBA
echo $HADAT
fi

Kimenet:


adam@gepecske~# ./test.sh
Nyomtato szamlalok lekerdezese...
10.61.4.30: 93710
10.61.4.20: 118038
10.61.4.51: 261827
10.61.5.50Timeout: No Response from 10.61.5.50.
: Kikapcsolva
adam@gepecske~# cat proba
Nyomtato szamlalok lekerdezese...
10.61.4.30: 93710
10.61.4.20: 118038
10.61.4.51: 261827
10.61.5.50: Kikapcsolva

---
- Indítsd újra a gépet! - Az egészet? - Nem, a felét...

Úgy tűnik megvan a megoldás. Köszönöm mindenkinek a segítséget!


adam@gepe~# cat proba
Subject: Nyomtato szamlalok
100.161.4.30 4700 Informatika titk: 93723
100.161.4.20 4400 Valami igazgat: 118218
100.161.4.51 4120 Senki: 261954
100.161.5.50 4210 Semmi nincs ott: Kikapcsolva

A script:


#!/bin/bash
#Nyomtato szamlalok lekerdezese

#Hiba tipusa legyen integer
declare -i hiba

#e-mail cimzettek
CIMZETTEK="valaki@valami.hu,abc@defghij.kl"

UDVOZLO="Nyomtato szamlalok lekerdezese..."
HIBA="-----=====##### HIBA! #####=====-----"
HADAT="Az adatok fajl nem talalhato!"
TARGY="Subject: Nyomtato szamlalok"

#Udvozlest kiirja
echo $UDVOZLO
#Ez lesz az e-mail targya es a fajl neve, amiben taroljuk a kimenetet
echo $TARGY > proba

# Teszteljuk, hogy letezik-e az adatok fajl
if test -f "adatok"; then

#For ciklus inditasa az asatok fajl sorszamaival megegyezo alkalommal -> (cat adatok | wc -l) adja meg a sorszamot
for i in `seq $(cat adatok | wc -l)`; do
#Beolvassuk a következo sorig a fajlt, majdaz aktualis sort eltaroljuk a $sor valtozoban
<------>sor=`head -n$i adatok | tail -1`
#Kiiratjuk a kepernyore a $sor valtozot miutan eltavolitottuk a sor vegerol a sortorest
<------>echo $sor | tr -d '\n'
#Ua. mint az elozo csak beleirjuk a fajlba
<------>`echo $sor | tr -d '\n'>>proba`
#Kiszedjuk az $ip valtozoba a $sor valtozo elso szavat, ami az IP cim
<------>ip=`echo $sor | awk '{print $1}'`
#snmpget segitsegevel lekerdezzuk az $ip cimu eszkozt, majd az esetleges hibat az >&1-re kuldjuk valamint taroljuk az $eredmeny valtozoban
<------>eredmeny=`snmpget -v2c -c public -m SNMPv2-MIB -M /opt/observium/mibs/rfc $ip -Ov iso.3.6.1.2.1.43.10.2.1.4.1.1 >&1`
#lekerdezzuk az elozo parancsra vonatkozoan, hogy hiba nelkul futott-e le, majd eltaroljuk a $hiba valtozoban (ha nem 0, akkor valami gebasz volt)
<------>hiba=`echo $?`
#a $szamlalo valtozoba taroljuk a ": " karaktereket, majd utana az $eredmeny masodik szavat pl.(: 3345)
<------>szamlalo=`echo $eredmeny | awk '{print ": " $2}'`
#ha az snmp lekerdezes soran hiba tortent ($hiba nagyobb, mint 0), akkor a szamlalo helyett csak annyit irunk ki, hogy kikapcsolva (+ mentjuk a fajlba is)
<------>if [ $hiba -gt 0 ]; then
<------> szamlalo=": Kikapcsolva"
<------> echo $szamlalo
<------> echo $szamlalo>>proba
#kulonben ha a lekerdezes hibatlanul lefutott, akkor csak kiirjuk a $szamlalo-t es a fajlba is beleirjuk
<------>else
<------> echo $szamlalo
<------> echo $szamlalo>>proba
#if ciklus vege
<------>fi
#for ciklus vege
done
#kulonben ha nincs meg a fajl, akkor kiirja, a hibakat
else
echo $HIBA
echo $HIBA>>proba
echo $HADAT
echo $HADAT>>proba
#if ciklus vege
fi

#e-mail kuldese

cat proba | sendmail -v $CIMZETTEK

Még annyit fogok finomítani, hogy a színes nyomtatóknál külön szükséges a színes és a fekete számláló, illetve jó lenne valahogy tabuláltan kiírni az adatokat (legalább a fájlba). Ez utóbbin még gondolkodom hogyan oldjam meg.
---
- Indítsd újra a gépet! - Az egészet? - Nem, a felét...

Mivel az echo alapértelmezetten minden kiírandó sor végére tesz egy sorvége jelet, ezért ha neked tabulálva kellenek az adatok, akkor ne 2 db echo-val írasd ki, hanem csak eggyel.


echo "$HIBA <TAB> $HADAT"

(Ha rosszul értem, akkor egy példával illustrálva írd már le, hogy milyen formában akarod azt a nyomorult adatot!)

=====
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?