[Rasberry Pi] Sysinfo Bash script

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • ndonkersloot
  • Registratie: September 2009
  • Laatst online: 01-10 16:01
Edit:
Volledig functioneel script in de volgende post:
Tiwazz in "[Rasberry Pi] Sysinfo Bash script"

Oorspronkelijk bericht:
Ik heb recentelijk een Rasberry Pi gekocht en heb hier Arch linux op gezet. Nou vond ik het leerzaam en leuk om een script te hebben waarmee ik een hoop systeem informatie in één oog opslag kan zien.

Uiteraard zijn op internet tal van dit soort scripts te vinden, echter zijn deze veelal in python en met copy-paste leer ik er niet zoveel van. Nu heb ik besloten om mijn script te maken in bash, dit omdat het dan niet nodig is om een pakket te instaleren zoals python. Ik heb nog geen ervaring met scripten in bash en zal dan misschien ook beginners fouten gemaakt hebben. Alles wat ik gebruikt heb heb ik gevonden in de --help van het commando of op het internet gevonden.

Nu heb ik mijn script zo goed als voltooid echter loop ik tegen enkele zaken aan en hoop hier een verklaring te vinden waarom dit zo is en wat ik moet doen om dit te verbeteren. Uiteraard heb ik oplossingen proberen te vinden op het internet, alleen ben hier niet in geslaagd.

Allereerst het script en daarna de console output.

Script:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#! /bin/bash
# Rasberry Pi Sysinfo version 1.0
# Author: Nando Donkersloot

###############
#DEFINE VALUES#
###############

#CLOCKS
CPU_CLOCK=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq) 
CORE_CLOCK=$(/opt/vc/bin/vcgencmd measure_clock core | cut -d= -f2)

#VOLTAGES
CORE_VOLT=$(/opt/vc/bin/vcgencmd measure_volts core | cut -d= -f2)
SDRAM_C_VOLT=$(/opt/vc/bin/vcgencmd measure_volts sdram_c | cut -d= -f2)
SDRAM_I_VOLT=$(/opt/vc/bin/vcgencmd measure_volts sdram_i | cut -d= -f2)
SDRAM_P_VOLT=$(/opt/vc/bin/vcgencmd measure_volts sdram_p | cut -d= -f2)

#TEMPERATURES
CPU_TEMP=$(cat /sys/class/thermal/thermal_zone0/temp)
GPU_TEMP=$(/opt/vc/bin/vcgencmd measure_temp | cut -d= -f2)

#FIRMWARE
VERSION=$(/opt/vc/bin/vcgencmd version | grep "version" | awk '{print $2}')

#SYSTEM
HOSTNAME=$( uname -n)
CPU_TYPE=$(sed -n '1 p' /proc/cpuinfo | cut -d: -f2)
CPU_FEATURES=$(sed -n '3 p' /proc/cpuinfo | cut -d: -f2)
SERIAL=$(sed -n '12 p' /proc/cpuinfo | cut -d: -f2)
KERNEL=$(uname -srm)

                    #UPTIME_CALCULATE

                    uptime=$(</proc/uptime)
                    uptime=${uptime%%.*}

                    seconds=$(( uptime%60 ))
                    minutes=$(( uptime/60%60 ))
                    hours=$(( uptime/60/60%24 ))
                    days=$(( uptime/60/60/24 ))
                    
UPTIME_CALCULATED=$(echo "$days days, $hours hours, $minutes minutes, $seconds seconds")

                    #MEMORY_CALCULATE

                    MEM_TOTAL=$(free -o | grep "Mem:" | cut -d: -f2 | awk '{print $1}')
                    MEM_USED=$(free -o | grep "Mem:" | cut -d: -f2 | awk '{print $2}')
                    MEM_FREE=$(free -o | grep "Mem:" | cut -d: -f2 | awk '{print $3}')
                    MEM_SHARED=$(free -o | grep "Mem:" | cut -d: -f2 | awk '{print $4}')
                    MEM_BUFFERS=$(free -o | grep "Mem:" | cut -d: -f2 | awk '{print $5}')
                    MEM_CACHED=$(free -o | grep "Mem:" | cut -d: -f2 | awk '{print $6}')

MEM_CALCULATED=$(echo $MEM_TOTAL Total $MEM_USED Used $MEM_FREE Free $MEM_SHARED Shared $MEM_BUFFERS Buffers $MEM_CACHED Cached)

                    #SWAP_CALCULATE

                    SWAP_TOTAL=$(free -o | grep "Swap:" | cut -d: -f2 | awk '{print $1}')
                    SWAP_USED=$(free -o | grep "Swap:" | cut -d: -f2 | awk '{print $2}')
                    SWAP_FREE=$(free -o | grep "Swap:" | cut -d: -f2 | awk '{print $3}')

SWAP_CALCULATED=$(echo $SWAP_TOTAL Total $SWAP_USED Used $SWAP_FREE Free)
NET_HARDWARE=$(sed -n '2 p' /sys/class/net/eth0/device/uevent | cut -d= -f2)
NET_MAC=$(cat /sys/class/net/eth0/address)

####[ Not Working - Need to Fix   ]#############
NET_LINK=$(cat /sys/class/net/eth0/carrier)    #
if [$NET_LINK=1]; then                         #
    $NET_LINK='Connected'                      #
else                                           #
    $NET_LINK='Disconnected'                   #
fi                                             #
################################################

                    #NET_SPEED
                    NET_CABLESPEED=$(cat /sys/class/net/eth0/speed)
                    NET_DUPLEX=$(cat /sys/class/net/eth0/duplex)
                    
NET_SPEED=$(echo $NET_CABLESPEED $NET_DUPLEX 'duplex')

##############
#PRINT VALUES#
##############

echo
echo '###[ Raspberry Pi Sysinfo  ]##########################################'
echo '###[ CLOCKS  ]########################################################'
echo CPU ....... : $(($CPU_CLOCK/1000))Mhz
echo CORE ...... : $(($CORE_CLOCK/1000))Mhz
echo
echo '###[ VOLTAGES  ]######################################################'
echo CORE ....... : $(($CORE_VOLT))
echo SDRAM_I .... : $(($SDRAM_I_VOLT))
echo SDRAM_V .... : $(($SDRAM_C_VOLT))
echo SDRAM_P .... : $(($SDRAM_P_VOLT))
echo 
echo '###[ TEMPERATURES  ]##################################################'
echo CPU Temp ....... : $(($CPU_TEMP/1000))°C / 85°C
echo GPU Temp ....... : $(($GPU_TEMP))
echo
echo '###[ FIRMWARE  ]######################################################'
echo Firmware .. : $(($VERSION))
echo
echo '###[ SYSTEM  ]########################################################'
echo Hostname .. : $(($HOSTNAME))
echo CPU ........: $(($CPU_TYPE))
echo FEATURES ...: $(($CPU_FEATURES))
echo SERIAL .....: $(($SERIAL))
echo KERNEL .....: $(($KERNEL))
echo UPTIME .....: $(($UPTIME_CALCULATED))
echo MEMORY .....: $(($MEM_CALCULATED))
echo SWAP .......: $(($SWAP_CALCULATED))
echo
echo '###[ NETWORK  ]#######################################################'
echo Interface . : eth0
echo Hardware .. : $(($NET_HARDWARE))
echo MAC Addr .. : $(($NET_MAC))
echo Cable ..... : $(($NET_LINK))
echo Link Speed  : $(($NET_SPEED))


Output:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
./sysinfo: line 68: [1#=1]: command not found
./sysinfo: line 71: 1#=Disconnected: command not found

###[ Raspberry Pi Sysinfo  ]##########################################
###[ CLOCKS  ]########################################################
CPU ....... : 700Mhz
CORE ...... : 250000Mhz

###[ VOLTAGES  ]######################################################
./sysinfo: line 92: 1.20V: syntax error: invalid arithmetic operator (error token is ".20V")
./sysinfo: line 93: 1.20V: syntax error: invalid arithmetic operator (error token is ".20V")
./sysinfo: line 94: 1.20V: syntax error: invalid arithmetic operator (error token is ".20V")
./sysinfo: line 95: 1.23V: syntax error: invalid arithmetic operator (error token is ".23V")

###[ TEMPERATURES  ]##################################################
CPU Temp ....... : 51°C / 85°C
./sysinfo: line 99: 51.4'C: syntax error: invalid arithmetic operator (error token is ".4'C")

###[ FIRMWARE  ]######################################################
./sysinfo: line 102: 8b570d997388ca7989be17029f79180f98465e3c: value too great for base (error token is "8b570d997388ca7989be17029f79180f98465e3c")

###[ SYSTEM  ]########################################################
Hostname .. : 0
./sysinfo: line 106: ARMv6-compatible processor rev 7 (v6l): syntax error in expression (error token is "processor rev 7 (v6l)")
./sysinfo: line 107: swp half thumb fastmult vfp edsp java tls : syntax error in expression (error token is "half thumb fastmult vfp edsp java tls ")
./sysinfo: line 108: <serialnumber>: value too great for base (error token is "<serialnumber>")
./sysinfo: line 109: Linux 3.6.11-14-ARCH+ armv6l: syntax error in expression (error token is "3.6.11-14-ARCH+ armv6l")
./sysinfo: line 110: 0 days, 11 hours, 42 minutes, 17 seconds: syntax error in expression (error token is "days, 11 hours, 42 minutes, 17 seconds")
./sysinfo: line 111: 472844 Total 70012 Used 402832 Free 0 Shared 11416 Buffers 25156 Cached: syntax error in expression (error token is "Total 70012 Used 402832 Free 0 Shared 11416 Buffers 25156 Cached")
./sysinfo: line 112: 0 Total 0 Used 0 Free: syntax error in expression (error token is "Total 0 Used 0 Free")

###[ NETWORK  ]#######################################################
Interface . : eth0
Hardware .. : 0
./sysinfo: line 117: <mac_adress>: syntax error in expression (error token is ":<mac_adress")
./sysinfo: line 118: 1#: invalid arithmetic base (error token is "1#")
./sysinfo: line 119: 100 full DUPLEX: syntax error in expression (error token is "full DUPLEX")
[nando@raspberrypi .scripts]$

Serialnumber en Mac adres heb ik gewijzigd zodat dit niet zichtbaar is.

Nou zijn er nogal wat errors en deze worden naar mijn inzien veroorzaakt doordat de uitkomst van de variable worden gelezen als commando ipv gewoon geprint. Nu heb ik van alles geprobeert om te zorgen dat echo gewoon puur alleen de regels weergeeft, maar toch lijkt het erop dat bash commando's probeert te zoeken in de regels.

Iemand een idee hoe ik dit kan verhelpen?

Probleem twee is dat onder het kopje system, hostname weergegeven wordt als "0". Dit geld ook voor Hardware onder het kopje Network.

Als 3de probleem onder het kopje Network probeer ik te controleren of de netwerk kabel is ingeplugt. Dit doe ik met een if else statement en wil als de waarde "1" is dat de variabele NET_LINK veranderd in "Connected" en als de waarde niet "1" is in "Disconnected". Hierna wil ik de variable NET_LINK gebruiken om te printen op de console wat dus de waarde Connected of Disconnected moet weergeven. Helaas werkt het niet zo en waarschijnlijk is mijn if else statement foutief, ik zie echter niet wat :(.

Ik hoop dat iemand mij kan helpen met bovenstaande fouten in mijn script. Uiteraard hoor ik ook wat er verder onlogisch is en beter kan of wat ik juist goed gedaan heb. Het is namelijk mijn eerste keer met bash scripting ;).

Modjes: Ik weet niet zeker of dit topic hier hoort of juist in Devschuur/Programming hoort. Volgens "Waar hoort mijn topic" hier. Mocht ik het toch mis hebben wordt ik graag verplaatst.

Fujifilm X-T3 | XF16mm f/2.8 | XF35mm f/2.0 | Flickr: ndonkersloot


Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:26

Hero of Time

Moderator LNX

There is only one Legend

Als je met [ (test) werkt, MOET je het altijd met spaties omringen. Dus if [ $var = $value ] ; then... Dat zal een aantal van je fouten oplossen. Net als je wiskundige oplossingen. Je gebruikt een keer netjes $((waarde/1000)), maar doet daarna alleen maar $((waarde)). Er wordt een wiskundige formule verwacht, geen plain echo van een waarde. Daarvoor heb je (( niet nodig, gewoon "$variable" is genoeg.

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 07:06
#68 [ is een programma genaamd test http://linux.about.com/library/cmd/blcmdl1_test.htm.
Door dit te doen:
code:
1
if [$NET_LINK=1]; then

Draai je een programma genaamd [$NET_LINK=1] en die bestaat niet. Daarom dus (met de -eq om te testen op getallen):
code:
1
if [ $NET_LINK -eq 1 ]; then

#71
code:
1
NET_LINK='Connected'

#92 en de rest
code:
1
echo $CORE_VOLT;


Daarnaast zijn vrijwel al je commando's te creëren in enkele sed calls. Sed is ontzettend krachtig. Vooral als je gebruik maakt van regular expressions.

[ Voor 4% gewijzigd door CurlyMo op 01-08-2013 23:37 ]

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 02-10 20:04

deadinspace

The what goes where now?

Tiwazz schreef op donderdag 01 augustus 2013 @ 22:30:
Uiteraard zijn op internet tal van dit soort scripts te vinden, echter zijn deze veelal in python en met copy-paste leer ik er niet zoveel van. Nu heb ik besloten om mijn script te maken in bash, dit omdat het dan niet nodig is om een pakket te instaleren zoals python.
Python wordt veel gebruikt onder Linux (zeker op de Pi voorzover ik weet); het is dan ook geen rare en ook zeker geen slechte keuze om te gebruiken. Dat betekent natuurlijk niet dat je je script niet in bash mag schrijven hoor, maar je hoeft je echt niet in bochten te wringen om python te mijden :)
Alles wat ik gebruikt heb heb ik gevonden in de --help van het commando of op het internet gevonden.
Wat ook een nuttige bron van informatie kan zijn: man-pages. Als de man-pages op je systeem geinstalleerd zijn, dan kun je documentatie over een command opvragen met simpelweg man commando. De manpage voor bash is waarschijnlijk wat te lang om prettig bruikbaar te zijn, en er staat sowieso niet in hoe je leert scripten, maar om op te zoeken wat de mogelijke opties van een commando zijn e.d. is het erg nuttig :)
code:
1
./sysinfo: line 68: [1#=1]: command not found
Ja, dat is wel een beetje een beginnersfout :)

Shell-scripting is (in tegenstelling tot een "echte" programmeertaal) voor een heel groot gedeelte het aanroepen van andere programma's. "if" is daar een voorbeeld van; if zelf is onderdeel van bash, geen extern programma, maar wat na if komt is wel degelijk een extern programma. Daar kun je in principe elk programma neerzetten dat je aan kunt roepen. De if is dan waar als dat programma "succesvol" afsluit, en onwaar als dat programma "onsuccesvol" afsluit. Een voorbeeldje met ls:
% if ls /etc/passwd; then echo yes; else echo nope; fi                      
/etc/passwd
yes
% if ls /etc/grizzlybear; then echo yes; else echo nope; fi        
ls: cannot access /etc/grizzlybear: No such file or directory
nope

In jouw constructie
if [$NET_LINK=1]

wordt $NET_LINK vervangen door "1#", dus dat wordt:
if [1#=1]

En daarin probeert bash "[1#=1]" uit te voeren als programma, en dat programma bestaat niet. Dus dat gaat mis. Het programma om variabelen te vergelijken (en nog wel meer) is [ . Als je een spatie na [ plaatst, dan snapt bash dat dat het programma is en de rest argumenten voor dat programma. Zo dus:
if [ 1#=1]

Dat zal nog steeds mis gaan, want 1#=1] is één argument, en dat snapt [ niet. Hoeveel argumenten [ verwacht hangt er van af wat je wil doen, maar voor vergelijkingen zijn dat er vier: waarde 1, =, waarde 2, en ] . Je zult die dus allemaal met spaties moeten scheiden, want als er spaties tussen staan dan snapt bash dat het losse argumenten zijn in plaats van één groot argument, en dan geeft bash ze los door aan [ . En dan gaat het goed!

Behalve dan dat je eerste waarde "1#" is in plaats van "1". Probeer er zelf maar eens achter te komen waar dat vandaan komt ;)
./sysinfo: line 71: 1#=Disconnected: command not found
Ok, je if ging de mist in; omdat hij het programma niet kon vinden klaagde bash en voert hij de else uit. En daar gaat ook wat mis. Om te snappen wat daar mis gaat moet je je indenken dat bash eerst overal $NET_LINK vervangt door #1. Er komt dus te staan #1='Disconnected', en dat snapt bash (terecht) niet. Je hebt dit al eerder goed gedaan, dus daar moet je ook wel uitkomen!
code:
1
./sysinfo: line 92: 1.20V: syntax error: invalid arithmetic operator (error token is ".20V")
Hiervoor zou ik zeggen: kijk eens hier naar. Dan zie je denk ik wel wat het probleem is :)

Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 07:06
deadinspace schreef op donderdag 01 augustus 2013 @ 23:54:
De if is dan waar als dat programma "succesvol" afsluit, en onwaar als dat programma "onsuccesvol" afsluit.
Dat kan overigens ook zonder if. Dit werkt ook prima:
code:
1
2
grep -c 1 /sys/class/net/eth0/carrier &>/dev/null && NET_LINK="connected" || NET_LINK="disconnected";
echo $NET_LINK;

[ Voor 5% gewijzigd door CurlyMo op 02-08-2013 00:00 ]

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • ndonkersloot
  • Registratie: September 2009
  • Laatst online: 01-10 16:01
Heel erg bedankt voor alle reacties. Helaas kan ik niet direct mijn script aanpassen, heb een huis gekocht en het is momenteel werken, klussen, slapen > werken, klussen, slapen.

Nu begrijp ik het beter, had echt gedacht dat [ gewoon syntax was van de if, maar dat is dus een commando.

Maar aangezien if een commando wilt zou het ook zo moeten kunnen toch?

code:
1
2
3
4
5
6
7
if grep -q 1 /sys/class/net/eth0/carrier ; then
    NET_LINK="Connected"
else
    NET_LINK="Disconnected"
fi

echo $NET_LINK


Ik heb dit uit mijn blote bol getypt zonder te checken in bash dus er zou wel eens iets stoms kunnen staan, maar volgens mij kan het zo.

Echt heel erg bedankt voor iedereen zijn reactie!

Fujifilm X-T3 | XF16mm f/2.8 | XF35mm f/2.0 | Flickr: ndonkersloot


Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:26

Hero of Time

Moderator LNX

There is only one Legend

Om eventuele vreemde uitvoer te voorkomen, is het handig om '> /dev/null' voor de ; te zetten. Dan krijg je dit:
code:
1
if grep -q 1 /sys/class/net/eth0/carrier > /dev/null ; then

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • ihre
  • Registratie: Juni 2004
  • Laatst online: 12-02 09:36
Nog een andere tip (zelfde resultaat, maar dan zonder grep of cut, alleen awk):

code:
1
MEM_TOTAL=$(free -o | grep "Mem:" | cut -d: -f2 | awk '{print $1}')


Is hetzelfde als:

code:
1
MEM_TOTAL=$(free -o | awk '/Mem:/{print $2}')


:)

[ Voor 3% gewijzigd door ihre op 05-08-2013 22:48 ]


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 07:06
Of als regular expressions je beter liggen:
code:
1
free -o | sed -ne 's/\(Mem:[\ ]\{1,\}\)\([0-9]\{1,\}\)\(.*\)/\2/p'

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:26

Hero of Time

Moderator LNX

There is only one Legend

CurlyMo schreef op maandag 05 augustus 2013 @ 22:58:
Of als regular expressions je beter liggen:
code:
1
free -o | sed -ne 's/\(Mem:[\ ]\{1,\}\)\([0-9]\{1,\}\)\(.*\)/\2/p'
Waar we nu geen moer aan hebben omdat je niet uitlegt wat het nou precies doet. Wil je dat alsnog even doen? Staat wel zo netjes, we willen hier allemaal wat leren.

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 07:06
Ja tuurlijk:
code:
1
free -o | sed -ne 's/\(Mem:[\ ]\{1,\}\)\([0-9]\{1,\}\)\(.*\)/\2/p'


-n Onderdruk alle uitvoer van sed
-e Laat weten dat er een commando aan komt. Bij één expressie is dat overbodig.

s Geeft aan dat er een search / replace commando wordt gecreëerd. Oftewel / search / replace /

Search (inclusief de juiste escapes):
\(Mem:[\ ]\{1,\}\) Zoek naar een match met Mem: gevold door 1 of meerdere spaties
\([0-9]\{1,\}\) Zoek naar een getal van tenminste 1 decimaal gevolgd op deze eerste match
\(.*\) Match alles wat er na de eerste twee matches komt

Replace:
\2 Print alleen de tweede match, dus degene met de [0-9]

Matches worden alleen opgeslagen in deze \1, \2, \3 "variabelen" mits de ze tussen haakjes staan ( .. ).

Dit had dus ook gewerkt aangezien er nu maar 1 match tussen haakjes staat dus je gewoon alleen de \1 kan en hoeft te gebruiken
code:
1
free -o | sed -n 's/Mem:[\ ]\{1,\}\([0-9]\{1,\}\).*/\1/p'


p Zet toch het printen van sed weer aan, maar dan alleen voor de match

Dan zal ik gelijk de awk even uitleggen :P :

code:
1
free -o | awk '/Mem:/{print $2}'


Ook de awk werkt in dit geval in search / replace modus net zoals bij de sed.

Mem: Zoek naar een regel waarin een Mem: voorkomt
{print $2} Print van die regel de waarde die in de tweede kolom te vinden is*

{ ... } Deze haakjes werken zoals een de haakjes van een standaard conditie. Alles wat er tussen die haakjes staat wordt na de match uitgevoerd.

*Kolommen kunnen afgescheiden worden door spaties of tabs

[ Voor 11% gewijzigd door CurlyMo op 05-08-2013 23:52 ]

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • ndonkersloot
  • Registratie: September 2009
  • Laatst online: 01-10 16:01
Ik heb vandaag nog wat aanpassingen gemaakt aan het script en het functioneert nu helemaal! De if heb ik aangepast zoals enkele posts terug te vinden is. Het zij wel met /dev/null om vreemde output te voorkomen. Bedankt Hero of Time!

De errors bij de voltages heb ik opgelost door niet wiskundige variabelen aan te roepen met $Variabel ipv $(($Variabel)).

Nu het script functioneel is ga ik me bezig houden met het verkorten van berekeningen om het zo compact en overzichtelijk mogelijk te houden. Zodra dit gebeurt is plaats ik het hier nogmaals om te kijken hoe ik het gedaan heb en of er nog meer verbeterd kan worden.

@ihre
Bedankt hiervoor. Ik had vandaag wat meer gelezen over awk en was van plan om het ook zo te gaan aanpakken, veel cleaner!

@CurlyMo
Bedankt voor de enorme uitleg, maakt het allemaal wat helderder. Je alternatieve oplossing met sed is me wel duidelijk na je uitleg maar naar mijn idee redelijk ingewikkeld in verglijking met awk. Ik denk dat ik dan ook awk ga gebruiken :).

@DeadinSpace
Enorm bedankt voor je flinke uitleg heeft een hele hoop duidelijk gemaakt. Eèn ding wat ik echter niet begrijp na er lang over nagedacht te hebben is waarom in het oorspronkelijke script waarde 1#=1 terug komt.

Hoezo wordt $NET_LINK in [$NET_LINK=1] weergegeven als 1#? Komt dat door de $ dat het commando [ deze input niet verwacht ofzo?

Fujifilm X-T3 | XF16mm f/2.8 | XF35mm f/2.0 | Flickr: ndonkersloot


Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:26

Hero of Time

Moderator LNX

There is only one Legend

Nog even iets verder gekeken en het redirecten met &>/dev/null gooit alles daarheen, ipv alleen stdout. Dan zie je op je shell ook niets als je 'm handmatig draait.
Zie ook dit:
code:
1
2
3
4
$ grep -q 1 /sys/class/net/eth0/carrier > /dev/null
grep: /sys/class/net/eth0/carrier: Invalid argument
$ grep -q 1 /sys/class/net/eth0/carrier &> /dev/null
$

Het systeem waar ik mee test heeft 2 interfaces, eth0 heeft geen link, eth1 wel. Je kan trouwens de return code opvragen van je laatst gedraaide commando via "echo $?". In mijn geval zou het 2 opleveren, error.

Voor je $NET_LINK dat 1# wordt, geen idee. Je hebt geen directe hekjes in je commando staan voor output, dus het zou er niet moeten staan. Net zelf even getest en ook hier krijg ik het niet.

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 07:06
Tiwazz schreef op dinsdag 06 augustus 2013 @ 00:41:
@CurlyMo
Bedankt voor de enorme uitleg, maakt het allemaal wat helderder. Je alternatieve oplossing met sed is me wel duidelijk na je uitleg maar naar mijn idee redelijk ingewikkeld in verglijking met awk. Ik denk dat ik dan ook awk ga gebruiken :).
Realiseer dat je van zowel AWK en SED maar een klein topje van de ijsberg heb gezien. Beiden zijn namelijk erg krachtig. Maar inderdaad voor zoiets marginaals als dit is AWK makkelijker te gebruiken dan SED.
Hero of Time schreef op dinsdag 06 augustus 2013 @ 09:51:
Het systeem waar ik mee test heeft 2 interfaces, eth0 heeft geen link, eth1 wel. Je kan trouwens de return code opvragen van je laatst gedraaide commando via "echo $?". In mijn geval zou het 2 opleveren, error.
Even het volgende voorbeeld terughalen:
code:
1
2
3
4
5
6
7
8
9
10
11
root@pi:~# cat /sys/class/net/eth0/carrier
1
root@pi:~# grep -c 1 /sys/class/net/eth0/carrier; echo $?;
1
0
root@pi:~# grep -c 0 /sys/class/net/eth0/carrier; echo $?;
0
1
root@pi:~# grep -c 1 /sys/class/net/eth0/carrier &>/dev/null && NET_LINK="connected" || NET_LINK="disconnected";
root@pi:~# echo $NET_LINK
connected

Het eerste getal is de uitvoer van het grep commando, het tweede getal de return code.

Een 0 betekent altijd succes, anders dan 0 is falen. Het eerste grep commando is dus geslaagd, het tweede niet.

Die && en || werken hier dan ook niet op de daadwerkelijke uitvoer van grep maar op de waarde van de return code. Als je dus iets met deze return code wilt doen, dan is dit voorbeeld dus het makkelijkst.

Stel nu je wilt twee schijven mounten maar de eerste bestaat niet. Dan zal nu je bash script stoppen bij het eerste commando, ondanks dat de tweede wel succesvol zou kunnen zijn.
code:
1
2
mount /dev/sda1 /mnt/usb0;
mount /dev/sda2 /mnt/usb1;

Om dit op te lossen doe je het volgende.
code:
1
2
mount /dev/sda1 /mnt/usb0 || return true;
mount /dev/sda2 /mnt/usb1 || return true;

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:26

Hero of Time

Moderator LNX

There is only one Legend

CurlyMo schreef op dinsdag 06 augustus 2013 @ 10:19:
Stel nu je wilt twee schijven mounten maar de eerste bestaat niet. Dan zal nu je bash script stoppen bij het eerste commando, ondanks dat de tweede wel succesvol zou kunnen zijn.
code:
1
2
mount /dev/sda1 /mnt/usb0;
mount /dev/sda2 /mnt/usb1;

Om dit op te lossen doe je het volgende.
code:
1
2
mount /dev/sda1 /mnt/usb0 || return true;
mount /dev/sda2 /mnt/usb1 || return true;
Eh, je zet gewoon geen ; aan het einde van de regel om de tweede toch te mounten? Wat je nu aandraagt is te vergelijken met useless use of cat. Bovendien zal je met je "|| return true" verkeerde informatie terugkrijgen. Je wilt weten of het succesvol is of niet, met je 'return true' krijg je altijd een success terug, ongeacht of het heeft gefaald of niet. Niet erg handig als je juist wilt weten of iets goed of fout is gegaan.

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 07:06
Hero of Time schreef op dinsdag 06 augustus 2013 @ 10:42:
[...]

Eh, je zet gewoon geen ; aan het einde van de regel om de tweede toch te mounten? Wat je nu aandraagt is te vergelijken met useless use of cat. Bovendien zal je met je "|| return true" verkeerde informatie terugkrijgen. Je wilt weten of het succesvol is of niet, met je 'return true' krijg je altijd een success terug, ongeacht of het heeft gefaald of niet. Niet erg handig als je juist wilt weten of iets goed of fout is gegaan.
Die ; is voor mij een automatisme. Het is daarnaast maar wat je doel is. Je zit niet altijd te wachten op een uitgebreide log functie. Je wilt dat iets gebeurt, en als dat niet gebeurt dan is dat geen probleem. Zolang het script maar niet faalt. Daarom forceer je een return true zodat tenminste niet je hele script stopt. Ik gaf dus het voorbeeld om aan te geven wat de mogelijkheden zijn om een bepaald probleem op te lossen.

Neem dit conceptuele voorbeeld waarin we alle test woorden uit een bepaald bestand moeten halen.
code:
1
sed -i '/test/d' /home/test 2>/dev/null || return true;

Als de gebruiker dat zelf al gedaan heeft prima. Als het bestand niet meer bestaat dan is het geen probleem meer want dan is bijv. het betreffende programma niet meer geïnstalleerd. Je kan in dit geval ook wel dit doen:
code:
1
2
3
if [ -f /home/test ] && [ $(grep -c test /home/test) -gt 0 ]; then
    sed -i '/test/d' /home/test
fi

Maar de werking blijft aan het eind toch hetzelfde.

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 02-10 20:04

deadinspace

The what goes where now?

Tiwazz schreef op zondag 04 augustus 2013 @ 10:38:
Maar aangezien if een commando wilt zou het ook zo moeten kunnen toch?
if grep -q 1 ...
Jep, dat had je snel door :)
Hero of Time schreef op zondag 04 augustus 2013 @ 11:28:
Om eventuele vreemde uitvoer te voorkomen, is het handig om '> /dev/null' voor de ; te zetten. Dan krijg je dit:
code:
1
if grep -q 1 /sys/class/net/eth0/carrier > /dev/null ; then
Dat hangt er een beetje van af. > redirect stdout, en daar zou grep al niks meer op moeten geven vanwege de -q die Tiwazz al gebruikte. Wel kun je stderr afvangen met bv 2>, maar of je foutmeldingen wil verbergen hangt van de situatie af natuurlijk :)
Tiwazz schreef op dinsdag 06 augustus 2013 @ 00:41:
@DeadinSpace
Enorm bedankt voor je flinke uitleg heeft een hele hoop duidelijk gemaakt. Eèn ding wat ik echter niet begrijp na er lang over nagedacht te hebben is waarom in het oorspronkelijke script waarde 1#=1 terug komt.

Hoezo wordt $NET_LINK in [$NET_LINK=1] weergegeven als 1#? Komt dat door de $ dat het commando [ deze input niet verwacht ofzo?
Nee, ik dacht dat het probleem zat in de toewijzing aan NETLINK (regel 67 in je originele script in de startpost); Daar staat
NET_LINK=$(cat /sys/class/net/eth0/carrier)    #

En ik dacht dat hij die # daar meenam als onderdeel van je toewijzing aan NET_LINK. Ik krijg dat op mijn eigen systemen alleen niet gereproduceerd, dus ik weet het niet zeker. Probeer in ieder geval dat hekje eens weg te halen :)
CurlyMo schreef op dinsdag 06 augustus 2013 @ 10:19:
Stel nu je wilt twee schijven mounten maar de eerste bestaat niet. Dan zal nu je bash script stoppen bij het eerste commando, ondanks dat de tweede wel succesvol zou kunnen zijn.
Dat is niet waar, standaard gaat bash (en vziw elke shell) gewoon door, tenzij je exit-on-error aanzet met set -e :)

Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 07:06
deadinspace schreef op woensdag 07 augustus 2013 @ 15:54:
Dat is niet waar, standaard gaat bash (en vziw elke shell) gewoon door, tenzij je exit-on-error aanzet met set -e :)
Mijn ervaring is toch echt anders. Een apt postint (ook shell) kan wel degelijk klappen op een foute return code. Maar goed. Het was conceptueel om te laten zien dat het kan. Welk doel het dient is dan maar even ten tweede ;)

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 02-10 20:04

deadinspace

The what goes where now?

CurlyMo schreef op woensdag 07 augustus 2013 @ 15:59:
Mijn ervaring is toch echt anders.
Het is toch echt zo :)

Als jij anders bent tegengekomen, dan zullen in die gevallen de scripts set -e bovenaan gehad hebben of aangeroepen zijn met -e. Voorbeeldje:
# cat test.sh
#! /bin/bash

mount /dev/foo /bar
mount /dev/baz /mnt
echo 'end'
# ./test.sh
mount: mount point /bar does not exist
mount: special device /dev/baz does not exist
end
Een apt postint (ook shell) kan wel degelijk klappen op een foute return code.
Debian postinst shell-scripts gebruiken dan ook vrijwel altijd set -e, zoals ze volgens de Debian policy moeten.
Maar goed. Het was conceptueel om te laten zien dat het kan. Wel doel het dient is dan maar even ten tweede ;)
Haha, klopt, maarja als het niet nodig is... :)

Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:26

Hero of Time

Moderator LNX

There is only one Legend

En mocht meneer denken dat 't door de ; komt, mis:
code:
1
2
3
4
5
6
cat test.sh 
#!/bin/bash

mount /dev/foo /bar;
mount /dev/bar /foo;
echo 'en nu?'

$ ./test.sh 
mount: only root can do that
mount: only root can do that
en nu?

$ sudo ./test.sh 
[sudo] password: 
mount: mount point /bar does not exist
mount: mount point /foo does not exist
en nu?

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 07:06
Hero of Time schreef op woensdag 07 augustus 2013 @ 18:11:
En mocht meneer denken dat 't door de ; komt, mis:
Dat heb ik volgens mij nergens gezegd :/

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:26

Hero of Time

Moderator LNX

There is only one Legend

Dat suggereerde je wel met je post:
Stel nu je wilt twee schijven mounten maar de eerste bestaat niet. Dan zal nu je bash script stoppen bij het eerste commando, ondanks dat de tweede wel succesvol zou kunnen zijn.
code:
1
2
mount /dev/sda1 /mnt/usb0;
mount /dev/sda2 /mnt/usb1;
Omdat je ; gebruikt, ongeacht of het nou automatisme is of niet (want het is nergens voor nodig in bash als 't op aparte regels staat), wordt de suggestie gewekt dat het door de ; komt dat het volgende commando dan niet uitgevoerd zou worden in geval de eerste een andere exit status dan 0 geeft.

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 07:06
Daar verschillen we dan van mening in. Het is nu dan in ieder geval duidelijk dat die ; weinig waarde heeft in bash.

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:26

Hero of Time

Moderator LNX

There is only one Legend

Het heeft alleen toegevoegde waarde als je de commando's op dezelfde regel zet. Zo kan je een hele riedel aan dingen schrijven dat moet afbreken als een van de kettingen faalt. Of juist moet doorgaan.

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 07:06
Klopt

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • ndonkersloot
  • Registratie: September 2009
  • Laatst online: 01-10 16:01
Wegens gebrek aan tijd heb ik geen verdere optimalisaties kunnen doorvoeren. Ik wil wel mijn huidig script hier posten zodat wellicht andere tweakers dit kunnen gebruiken voor zijn of haar rasberry :).

Mocht je feedback hebben is dit uiteraard altijd leuk en nuttig om te lezen.

Script:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#! /bin/bash
# Rasberry Pi Sysinfo version 1.0
# Author: Nando Donkersloot

###############
#DEFINE VALUES#
###############

#CLOCKS
CPU_CLOCK=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq) 
CORE_CLOCK=$(/opt/vc/bin/vcgencmd measure_clock core | cut -d= -f2)

#VOLTAGES
CORE_VOLT=$(/opt/vc/bin/vcgencmd measure_volts core | cut -d= -f2)
SDRAM_C_VOLT=$(/opt/vc/bin/vcgencmd measure_volts sdram_c | cut -d= -f2)
SDRAM_I_VOLT=$(/opt/vc/bin/vcgencmd measure_volts sdram_i | cut -d= -f2)
SDRAM_P_VOLT=$(/opt/vc/bin/vcgencmd measure_volts sdram_p | cut -d= -f2)

#TEMPERATURES
CPU_TEMP=$(cat /sys/class/thermal/thermal_zone0/temp)
GPU_TEMP=$(/opt/vc/bin/vcgencmd measure_temp | cut -d= -f2 |cut -d. -f1)

#FIRMWARE
VERSION=$(/opt/vc/bin/vcgencmd version | grep "version" | awk '{print $2}')

#SYSTEM
HOSTNAME=$(uname -n)
CPU_TYPE=$(sed -n '1 p' /proc/cpuinfo | cut -d: -f2)
CPU_FEATURES=$(sed -n '3 p' /proc/cpuinfo | cut -d: -f2)
SERIAL=$(sed -n '12 p' /proc/cpuinfo | cut -d: -f2)
KERNEL=$(uname -srm)

                    #UPTIME_CALCULATE

                    uptime=$(</proc/uptime)
                    uptime=${uptime%%.*}

                    seconds=$(( uptime%60 ))
                    minutes=$(( uptime/60%60 ))
                    hours=$(( uptime/60/60%24 ))
                    days=$(( uptime/60/60/24 ))
                    
UPTIME_CALCULATED=$(echo "$days days, $hours hours, $minutes minutes, $seconds seconds")

                    #MEMORY_CALCULATE

                    MEM_TOTAL=$(free -o | awk '/Mem:/{print $2}')
                    MEM_USED=$(free -o | awk '/Mem:/{print $3}')
                    MEM_FREE=$(free -o | awk '/Mem:/{print $4}')
                    MEM_SHARED=$(free -o | awk '/Mem:/{print $5}')
                    MEM_BUFFERS=$(free -o | awk '/Mem:/{print $6}')
                    MEM_CACHED=$(free -o | awk '/Mem:/{print $7}')
                    
MEM_CALCULATED1=$(echo $MEM_TOTAL Total $MEM_USED Used $MEM_FREE Free)
MEM_CALCULATED2=$(echo $MEM_SHARED Shared $MEM_BUFFERS Buffers $MEM_CACHED Cached)

                    #SWAP_CALCULATE

                    SWAP_TOTAL=$(free -o | awk '/Swap:/{print $2}')
                    SWAP_USED=$(free -o | awk '/Swap:/{print $3}')
                    SWAP_FREE=$(free -o | awk '/Swap:/{print $4}')

SWAP_CALCULATED=$(echo $SWAP_TOTAL Total $SWAP_USED Used $SWAP_FREE Free)
NET_HARDWARE=$(awk -F'=' '/DRIVER/{print $2}' /sys/class/net/eth0/device/uevent)
NET_MAC=$(cat /sys/class/net/eth0/address)

#NET_LINK
if grep -q 1 /sys/class/net/eth0/carrier > /dev/null ; then
    NET_LINK="Connected"
else
    NET_LINK="Disconnected"
fi


                    #NET_SPEED
                    NET_CABLESPEED=$(cat /sys/class/net/eth0/speed)
                    NET_DUPLEX=$(cat /sys/class/net/eth0/duplex)
                    
NET_SPEED=$(echo $NET_CABLESPEED $NET_DUPLEX 'duplex')

##############
#PRINT VALUES#
##############

echo
echo '###[ Raspberry Pi Sysinfo  ]##########################################'
echo '###[ CLOCKS  ]########################################################'
echo CPU ....... : $(($CPU_CLOCK/1000))Mhz
echo CORE ...... : $(($CORE_CLOCK/1000))Mhz
echo
echo '###[ VOLTAGES  ]######################################################'
echo CORE ....... : $CORE_VOLT
echo SDRAM_I .... : $SDRAM_I_VOLT
echo SDRAM_V .... : $SDRAM_C_VOLT
echo SDRAM_P .... : $SDRAM_P_VOLT
echo 
echo '###[ TEMPERATURES  ]##################################################'
echo CPU Temp ....... : $(($CPU_TEMP/1000))°C / 85°C
echo GPU Temp ....... : $GPU_TEMP°C
echo
echo '###[ FIRMWARE  ]######################################################'
echo Firmware .. : $VERSION
echo
echo '###[ SYSTEM  ]########################################################'
echo Hostname .. : $HOSTNAME
echo CPU ....... : $CPU_TYPE
echo FEATURES .. : $CPU_FEATURES
echo SERIAL .... : $SERIAL
echo KERNEL .... : $KERNEL
echo UPTIME .... : $UPTIME_CALCULATED
echo MEMORY .... : $MEM_CALCULATED1
echo ........... : $MEM_CALCULATED2
echo SWAP ...... : $SWAP_CALCULATED
echo
echo '###[ NETWORK  ]#######################################################'
echo Interface . : eth0
echo Hardware .. : $NET_HARDWARE
echo MAC Addr .. : $NET_MAC
echo Status .... : $NET_LINK
echo Cable Speed : $NET_SPEED


Output:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
###[ Raspberry Pi Sysinfo  ]##########################################
###[ CLOCKS  ]########################################################
CPU ....... : 700Mhz
CORE ...... : 250000Mhz

###[ VOLTAGES  ]######################################################
CORE ....... : 1.20V
SDRAM_I .... : 1.20V
SDRAM_V .... : 1.20V
SDRAM_P .... : 1.23V

###[ TEMPERATURES  ]##################################################
CPU Temp ....... : 52°C / 85°C
GPU Temp ....... : 53°C

###[ FIRMWARE  ]######################################################
Firmware .. : bbd9a1d2f00a5363141715936596950ddd1757e2

###[ SYSTEM  ]########################################################
Hostname .. : raspberrypi
CPU ....... : ARMv6-compatible processor rev 7 (v6l)
FEATURES .. : swp half thumb fastmult vfp edsp java tls
SERIAL .... : 000000000000000
KERNEL .... : Linux 3.6.11-14-ARCH+ armv6l
UPTIME .... : 17 days, 19 hours, 5 minutes, 21 seconds
MEMORY .... : 472844 Total 188180 Used 284664 Free
........... : 0 Shared 44972 Buffers 100288 Cached
SWAP ...... : 0 Total 0 Used 0 Free

###[ NETWORK  ]#######################################################
Interface . : eth0
Hardware .. : smsc95xx
MAC Addr .. : xx:xx:xx:xx:xx:xx
Status .... : Connected
Cable Speed : 100 full duplex

Fujifilm X-T3 | XF16mm f/2.8 | XF35mm f/2.0 | Flickr: ndonkersloot

Pagina: 1