Pagina 1 di 2

[Risolto][BASH] velocità di up/down nel terminale

Inviato: sabato 19 aprile 2014, 14:29
da Painbrain
ciao a tutti,

non riesco ad uscire da un problema.
devo trovare un comando in bash che mi generi a video (o in un file) la velocità ISTANTANEA in download e upload della rete in uso (eth0).

il problema è che trovo mille tool per MONITORARE la velocità in real time (bmon, speedometer, nload, vnstat e altro) ma non riesco a trovarne uno che mi tiri fuori il dato "statico" così che io lo possa poi prendere e scrivere in un file per farci altre cose.

qualcuno ha qualche consiglio da darmi? :)

grazie mille e buona Pasqua a tutti!

Re: [BASH] velocità di up/down nel terminale

Inviato: sabato 19 aprile 2014, 15:15
da 1001001
Ciao! Non sono sicuro di aver capito il tuo problema :) ma per quello che capisco io secondo me la soluzione potrebbe essere usare il comando ifstat (in particolare, usando gli argomenti opzionali delay e count)

Re: [BASH] velocità di up/down nel terminale

Inviato: sabato 19 aprile 2014, 15:42
da Painbrain
ifstat -i eth0 5 1 | tail -1 | tr '\t' ' '

FANTASTICOOOOOOOOOOOOOOOOOO!!!!!
grazie!!!

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: sabato 19 aprile 2014, 18:22
da 1001001
Di nulla! :) ciao! :ciao:

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: sabato 19 aprile 2014, 19:23
da Painbrain
ok
però come faccio ora a dividere i due numeri?

ifstat -i eth0 5 1 | tail -1 | tr '\t' ' '
come output mi da
1,38 2,54

come li prendo separatamente?

considerando che il 1,38 potrebbe anche essere 650,30 quindi diverso numero di cifre prima della virgola.

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: sabato 19 aprile 2014, 22:46
da UbuNuovo
Un modo potrebbe essere questo:

Codice: Seleziona tutto

8-) a='1,38 2,54'
8-) primo_n=$(echo $a | cut -d' ' -f1)
8-) secondo_n=$(echo $a | cut -d' ' -f2)
8-) echo $primo_n 
1,38
8-) echo $secondo_n 
2,54

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: domenica 20 aprile 2014, 18:47
da 1001001
UbuNuovo [url=http://forum.ubuntu-it.org/viewtopic.php?p=4566515#p4566515][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Un modo potrebbe essere questo:

Codice: Seleziona tutto

8-) a='1,38 2,54'
8-) primo_n=$(echo $a | cut -d' ' -f1)
8-) secondo_n=$(echo $a | cut -d' ' -f2)
8-) echo $primo_n 
1,38
8-) echo $secondo_n 
2,54
In realtà così non funziona, perché l'output di ifstat (a differenza della variabile a) è tipo:

Codice: Seleziona tutto

[un certo numero di spazi][NUMERO][un altro numero di spazi][NUMERO]
Ma soprattutto il problema è che il numero di spazi è variabile, perché i numeri sono allineati a destra nelle loro colonne. Quindi i campi in cui sono salvati i numeri (aka i possibili argomenti dell'opzione -f di cut per estrarre i due numeri) cambiano a seconda dell'output.
Le soluzioni possibili sono due:
1) salvare l'output in una variabile e poi usare il metodo proposto da UbuNuovo. Infatti se fai:

Codice: Seleziona tutto

mattia@replicant:Scrivania$ a=$(ifstat -i eth0 0.1 1 | tail -1)
mattia@replicant:Scrivania$ echo $a
87.82 16.00
la stampa attraverso echo "taglia" gli spazi aggiuntivi e quindi la chiamata a cut con argomenti -f 1 e -f 2 funziona:

Codice: Seleziona tutto

mattia@replicant:Scrivania$ echo $a | cut -d ' ' -f 1
87.82
mattia@replicant:Scrivania$ echo $a | cut -d ' ' -f 2
16.00
(EDIT: adesso che ci ripenso, probabilmente questo è quello che intendeva anche UbuNuovo...ho preferito lasciarlo comunque esplicitato, visto che, immagino per semplicità, aveva dato per scontato che, a differenza sua, tu nella variable a mettessi l'output di ifstat) :)
(EDIT 2: scusate, sarà il pranzo di pasqua che mi fa ragionare lentamente :) ho notato che hai messo una chiamata a tr alla fine del comando. Questo potrebbe in effetti far funzionare il metodo con cut in una sola chiamata (cioè mettendo cut in pipe alla fine del comando). Dico potrebbe perché sul mio computer (Ubuntu 12.04.4) ifstat in output usa spazi e non tabulazioni, quindi

Codice: Seleziona tutto

tr '\t' ' '
non ha nessun effetto sull'output stesso, e si presenta quindi il problema di cui parlo al punto 1. Spero di non aver fatto troppa confusione e di essermi fatto capire :) )[/b][/color]

2) l'altra possibilità (che secondo me taglia la testa al toro) è usare awk:

Codice: Seleziona tutto

mattia@replicant:Scrivania$ ifstat -i eth0 0.1 1 | tail -1 | awk '{print $1}'
73.34
mattia@replicant:Scrivania$ ifstat -i eth0 0.1 1 | tail -1 | awk '{print $2}'
56.59

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: domenica 20 aprile 2014, 19:09
da vaeVictis

Codice: Seleziona tutto

vaevictis@vaevictis-HAL:~$ output=( $( ifstat -i eth0 0.1 1 | tail -1 ) )
vaevictis@vaevictis-HAL:~$ echo ${output[0]}
87.82
vaevictis@vaevictis-HAL:~$ echo ${output[1]}
16.00

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: domenica 20 aprile 2014, 22:16
da UbuNuovo
Allora..., non ho letto con cognizione di causa quello che hai scritto prima (troppo psichedelico).
Esco ora dal pranzo di Pasqua (non cena) ho il mal di testa.
"Se Dante era un poeta colmo di versi divini"... "io sono colmo di vini diversi!"
Quello che ho proposto si basa su quello che tu hai considerato come output del comando...
Puoi usare vari metodi: array (VaeVictis docet), oppure cut o

Codice: Seleziona tutto

8-) echo "$a" | grep -Po '^.*(?= )'
1,38
8-) echo "$a" | grep -Po '( )\K.*$'
2,54

8-) echo "$a" | awk '{print $1}'
1,38
8-) echo "$a" | awk '{print $2}'
2,54
[code]
Se poi devi fare operazioni sui valori, considera che...
Bash fa operazioni solo su interi, quindi conviene usare "bc".
Occhio che "bc" vuole il punto decimale, se ne frega delle impostazioni italiane di LOCALE
[code]8-) a='1,38 2,54'
8-) a=$(echo "$a" | tr ',' '.')		# converto i caratteri virgola in punto
8-) echo $a
1.38 2.54
# separazione e calcolo con bc

Codice: Seleziona tutto

8-) primo=$(echo $a | cut -d' ' -f1)
8-) secondo=$(echo $a | cut -d' ' -f2)
8-) echo "$primo + $secondo" | bc
3.92
# per ottenere un dato numero di decimali (superiore a quelli presenti), puoi indicali con 'scale=N;'
# Ricordasi che bc non arrotonda ma tronca i decimali.

Codice: Seleziona tutto

8-) echo "$primo * $secondo" | bc
3.50

8-) echo "scale=4; $primo * $secondo" | bc
3.5052

# oppure con "-l", senza indicare il numero di decimali (considera fino a 20 decimali)
8-) echo "$primo * $secondo" | bc -l
3.5052
# altrimenti si può aumentare il numero di decimali di almeno uno dei valori

Codice: Seleziona tutto

8-) primo=1.3800000000
8-) echo "$primo * $secondo" | bc
3.5052000000
Credo che ora tu abbia tutto quello che serve.
Facci sapere. :)

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: domenica 20 aprile 2014, 22:51
da vaeVictis
Al posto del grep o awk userei direttamente le operazioni di bash su stringa.

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: domenica 20 aprile 2014, 22:55
da UbuNuovo
i metodi non mancano ;)

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: domenica 20 aprile 2014, 22:59
da vaeVictis
Soprattutto quelli minimalisti :)

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: lunedì 21 aprile 2014, 1:42
da Painbrain
1001001 [url=http://forum.ubuntu-it.org/viewtopic.php?p=4566942#p4566942][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:
UbuNuovo [url=http://forum.ubuntu-it.org/viewtopic.php?p=4566515#p4566515][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Un modo potrebbe essere questo:

Codice: Seleziona tutto

8-) a='1,38 2,54'
8-) primo_n=$(echo $a | cut -d' ' -f1)
8-) secondo_n=$(echo $a | cut -d' ' -f2)
8-) echo $primo_n 
1,38
8-) echo $secondo_n 
2,54
In realtà così non funziona, perché l'output di ifstat (a differenza della variabile a) è tipo:

Codice: Seleziona tutto

[un certo numero di spazi][NUMERO][un altro numero di spazi][NUMERO]
Ma soprattutto il problema è che il numero di spazi è variabile, perché i numeri sono allineati a destra nelle loro colonne. Quindi i campi in cui sono salvati i numeri (aka i possibili argomenti dell'opzione -f di cut per estrarre i due numeri) cambiano a seconda dell'output.
Le soluzioni possibili sono due:
1) salvare l'output in una variabile e poi usare il metodo proposto da UbuNuovo. Infatti se fai:

Codice: Seleziona tutto

mattia@replicant:Scrivania$ a=$(ifstat -i eth0 0.1 1 | tail -1)
mattia@replicant:Scrivania$ echo $a
87.82 16.00
la stampa attraverso echo "taglia" gli spazi aggiuntivi e quindi la chiamata a cut con argomenti -f 1 e -f 2 funziona:

Codice: Seleziona tutto

mattia@replicant:Scrivania$ echo $a | cut -d ' ' -f 1
87.82
mattia@replicant:Scrivania$ echo $a | cut -d ' ' -f 2
16.00
(EDIT: adesso che ci ripenso, probabilmente questo è quello che intendeva anche UbuNuovo...ho preferito lasciarlo comunque esplicitato, visto che, immagino per semplicità, aveva dato per scontato che, a differenza sua, tu nella variable a mettessi l'output di ifstat) :)
(EDIT 2: scusate, sarà il pranzo di pasqua che mi fa ragionare lentamente :) ho notato che hai messo una chiamata a tr alla fine del comando. Questo potrebbe in effetti far funzionare il metodo con cut in una sola chiamata (cioè mettendo cut in pipe alla fine del comando). Dico potrebbe perché sul mio computer (Ubuntu 12.04.4) ifstat in output usa spazi e non tabulazioni, quindi

Codice: Seleziona tutto

tr '\t' ' '
non ha nessun effetto sull'output stesso, e si presenta quindi il problema di cui parlo al punto 1. Spero di non aver fatto troppa confusione e di essermi fatto capire :) )[/b][/color]

2) l'altra possibilità (che secondo me taglia la testa al toro) è usare awk:

Codice: Seleziona tutto

mattia@replicant:Scrivania$ ifstat -i eth0 0.1 1 | tail -1 | awk '{print $1}'
73.34
mattia@replicant:Scrivania$ ifstat -i eth0 0.1 1 | tail -1 | awk '{print $2}'
56.59
grazie mille!
era quello che volevo :)
la soluzione con awk risolve tutto con veramente poco.

unica cosa invece di 0.1 credo sia piu corretto 1, cosi si ha come unità di misura kb/secondo

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: lunedì 21 aprile 2014, 12:08
da 1001001
Painbrain [url=http://forum.ubuntu-it.org/viewtopic.php?p=4567263#p4567263][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto: grazie mille!
era quello che volevo :)
la soluzione con awk risolve tutto con veramente poco.
Di nulla!

Painbrain [url=http://forum.ubuntu-it.org/viewtopic.php?p=4567263#p4567263][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:unica cosa invece di 0.1 credo sia piu corretto 1, cosi si ha come unità di misura kb/secondo
In realtà la misurazione è sempre in kB/s, il valore passato per delay (cioè il primo argomento numerico) indica solo ogni quanto effettuare le diverse misurazioni (nel caso in cui count, il secondo argomento numerico, sia maggiore di 1 - nel nostro caso, in cui vale 1, è solo il tempo che passa fra il lancio del comando e la misurazione). Comunque puoi anche mettere 1, non cambia nulla :)

Nota che, come ha giustamente sottolineato vaeVictis, questa non è esattamente una soluzione minimale. Nel senso che come minimo prevede che sulla macchina su cui lanci lo script che stai scrivendo sia installato awk (cosa che è generalmente vera, ma su cui non puoi fare affidamento al 100%). Usando invece un array, come mostrato nel suo messaggio, stai usando solo bash, cosa che incrementa la portabilità del tuo codice. Sta a te poi decidere quanto questo sia un problema (leggasi: se lo stai scrivendo per te e te solo puoi anche "fregartene", se no facci un pensierino :) )

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: lunedì 21 aprile 2014, 14:01
da Painbrain
No problem,
Non lo devo "portare", deve stare sul mio serverino e awk c'é.

Hai ragione inoltre sulla questione 0,1 e 1 riguardante la velocità.

Ciao! :)

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: lunedì 21 aprile 2014, 16:00
da 1001001
Ottimo! :) ciao!

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: lunedì 21 aprile 2014, 16:13
da vaeVictis
Dal momento che l'interlocutore è 1001001, mi esprimo serenamente e francamente.
Non è una sola questione di portabilità del codice.
Quando ho detto "minimale" e in generale quando mi sono espresso in modo volutamente sibillino, non mi stavo riferendo in particolar modo alla presenza o meno di awk e a questo tipo di problematiche. Anche perché da questo punto di vista non è neanche detto che sul server sia installata una shell che ha gli array.
La questione è un'altra.
Anche qualora sulla tua macchina fosse presente uno che fa la sostituzione la fa a mano... non è detto che tu debba usarlo per forza.
Soprattutto quando, come in questo caso, si risolve il problema complicandosi la vita e assumendo dei "principi" completamente sbagliati.
Capisco che Painbrain non sia interessato a questioni di "bontà" del codice... ma il problema è proprio qui.
Mi spiego.
Il comando che usa awk prevede l'utilizzo di una riga di codice aggiuntiva per l'estrazione di ogni singolo campo. In questo caso i campi sono due, quindi è poca cosa.
Ma se un domani si dovesse rimettere mano allo script perché l'output del comando cambia e magari vengono aggiunti ulteriori campi?
E se un domani si dovesse affrontare da capo un problema analogo ma, di nuovo, con un numero di campi "enorme"?
Che fai... dai un comando per ogni campo da estrarre? La risposta è sì :)

Poi c'è un altro punto. E se questo script passa di mano e va a finire in mano a qualcun'altro non molto "addentro" a questioni "tecniche"?
La risposta è che prolifererebbe un modo "sbagliato" di codificare.

Sono ragionamenti di questo tipo che mi portano a pensare che sia meglio usare lo stretto indispensabile e in modo oculato.
Ciao.

Re: [BASH] velocità di up/down nel terminale [RISOLTO]

Inviato: lunedì 21 aprile 2014, 16:18
da Painbrain
Sulla teoria della programmazione piu minimale e "esportabile" possibile mi trovi d'accordo.

Non posso aiutare a riguardo ma metterò un QUASI RISOLTO nel titolo per laaciare il dubbio, sempre che poi non fiorisca una soluzione piu consona ai principi di buona programmazione.

Re: [BASH] velocità di up/down nel terminale [quasi RISOLTO]

Inviato: lunedì 21 aprile 2014, 16:37
da vaeVictis
Scusami ma non ti seguo.
A prescindere dal tag "quasi RISOLTO" nel titolo che, più che lasciare un dubbio, è proprio contrario al regolamento del forum e quindi dovresti ridurlo a RISOLTO o levarlo, quello che non capisco è cosa dovrebbe "fiorire".

Hai avuto tutti gli esempi nel corso della discussione.
Non so, forse ti è sfuggito semplicemente questo messaggio :)
vaeVictis ha scritto:

Codice: Seleziona tutto

vaevictis@vaevictis-HAL:~$ output=( $( ifstat -i eth0 0.1 1 | tail -1 ) )
vaevictis@vaevictis-HAL:~$ echo ${output[0]}
87.82
vaevictis@vaevictis-HAL:~$ echo ${output[1]}
16.00

Re: [BASH] velocità di up/down nel terminale [quasi RISOLTO]

Inviato: lunedì 21 aprile 2014, 17:05
da Mdfalcubo
Per fruibilità e chiarezza verso chi usa la ricerca, togli quel quasi risolto: o lo è o non lo é. Grazie.