Aloinpa etsiä keinoa jolla saisi tietää onko kovalevy puolijohdetyyppinen vaiko mekaaninen. BASH:issa kaikkea voi viilata loputtomiin, mutta tällähetkellä skripti on seuraavanlainen:
#!/bin/bash
function Kovalevyntyyppi () { [[ $(udevadm info --query=all --name=/dev/$1 | grep DEVLINKS= | awk '{print $3}') ]] && echo 'levy:'$1' on puolijohdetyyppinen' || echo 'levy:'$1' on mekaaninen' ;}
# [[ -f /sys/block/$1/queue/rotational ]] && ( [[ $(cat /sys/block/$1/queue/rotational) -eq 0 ]] && echo 'levy:'$1' on puolijohdetyyppinen' || echo 'levy:'$1' on mekaaninen' ) || echo echo 'levyä:'$1' ei ole' # tämä on "virallinen" tapa määritellä levyntyyppi, mutta se ei toimi usb-levyjen kanssa
function ListaaLevyt () {
apu=$(ls -lF /dev/disk/by-id | grep ata- | grep -o sd.$); [[ $apu ]] && echo ata:lla liitetyt levyt: $apu && { for apuu in $apu; do Kovalevyntyyppi $apuu; done }
echo
apu=$(ls -lF /dev/disk/by-id | grep usb- | grep -o sd.$); [[ $apu ]] && echo usb:llä liitetyt levyt: $apu && { for apuu in $apu; do Kovalevyntyyppi $apuu; done }
}
ListaaLevyt
- ja tuloste esimerkiksi seuraavanlainen:
ata:lla liitetyt levyt: sda sdb
levy:sda on puolijohdetyyppinen
levy:sdb on mekaaninen
usb:llä liitetyt levyt: sdd sdc
levy:sdd on puolijohdetyyppinen
levy:sdc on puolijohdetyyppinen
**
Tulipa tarve mitata prosessori-ytimien kuormitusta. Siihen sopivaksi skriptiksi osoittautui:
- ytimien määrä otetaan automaattisesti huomioon
#!/bin/bash
apu=0; while true; do
prosessorin_data=$( grep 'cpu'$apu /proc/stat)
[[ ! $prosessorin_data ]] && break
echo -n "ydin"$apu' '; echo $prosessorin_data | awk '{usage=($2+$4)*100/($2+$4+$5)} END {printf "%2.2f %s\n", usage,"%"}'
let apu++
done
Skriptin kokeilemiseksi aja se kun koneessa ei ole käynnissä mitään muuta (et siis saa roikkua netissä tämän kokeen aikana). Omassa neliytimisessä prosessorissani tulos oli seuraava:
- äskettäiset tapahtumat vaikuttavat, joten kannattaa odottaa minuutti ennenkuin ajaa skriptin. Tulos ei muten ole sama kuin mitä tulee järjestelmän valvonnassa.
ydin0 2.58%[[ $( apt-cache policy lm-sensors | grep "(ei mitään)" ) ]] && echo 'koneessasi ei ole pakettia nimeltä: lm-sensors . Haen sen' && sudo apt-get install lm-sensors
[[ $( apt-cache policy plotutils | grep "(ei mitään)" ) ]] && echo 'koneessasi ei ole pakettia nimeltä: plotutils . Haen sen' && sudo apt-get install plotutils
[[ $( apt-cache policy gv | grep "(ei mitään)" ) ]] && echo 'koneessasi ei ole pakettia nimeltä: gv . Haen sen' && sudo apt-get install gv
n=0; echo "" >~/xy_arvot
while true; do
apu=$(sensors -Au | grep -Po '(?<=_input: ).*' | tail -$(nproc) | awk '{t+=$0} END {print t/NF}') # lasketaan kaikkien ytimien lämpötilojen keskiarvo - niin monta kuin niitä onkin.
echo -e $n' ' $apu >> ~/xy_arvot
graph -T ps ~/xy_arvot > ~/plot.ps; gv ~/plot.ps &
let n+=2; sleep 2 # mittausten välillä noin 2 sekuntia - ajan suhteellinenkin arvo on melko merkityksetön
killall gv
done
ydin1 2.54%
ydin2 2.86%
ydin3 2.31%
Avaa sitten pääte (ubuntussa paina ctrl-alt-t) ja anna käsky: yes
- tuo käsky ajaa prosessoreissa prosessin joka tulostaa jatkuvasti: y.
Avaa sitten toinen pääte (ubuntussa paina taas ctrl-alt-t) ja aja kuormitusta mittaava skripti odotettuasi taas minuutin. Tuloksen pitäisi olla jotakin seuraavankaltaista:
ydin0 9.57%
ydin1 10.0%
ydin2 9.79%
ydin3 9.69%
- prosentit kasvavat mitä kauemmin odotat.
- tottakai skriptissä olisi parantamisen varaa taas loputtomiin; tämä on vain ensimmäiseksi mieleentullut.
**
Halusinpa saada mitatuksi prosessori-ytimen lämpötilan. Osoittautui että ytimen lämpötila on varsin epäselvä asia ja sen mittaava skripti olisi haastava tehtävä, mutta kestoltaan "ikuisuus-projekti". Tässä kuitenkin jonkinlainen versio joka suorittaa mittauksen kymmenen kertaa tulostaen Kovalevyn attribuuttien selville saamiseksi on lukemattomia konsteja. Niiden yhteinen piirre tuntuu olevan se, että ne vaativat sudo:a. Esimerkiksi käsky: blkid toimii näennäisesti ilman sudo:a, mutta lähemmin tarkasteltuna osottautuu että se vaatii sittenkin kunnolla toimiakseen sudo:a. Mutta toki konsti löytyy: otetaanpa esimerkiksi osiotyypin selvittäminen:
udevadm info -n /dev/sda1 -q property | grep -Po '(?<=ID_FS_TYPE=).*'
- ja samalla periaatteella saa muitakin attribuuttejajokakerran mittaustuloksen ja tulostaa lopuksi mittaustulosten keskiarvon:
#!/bin/bash
[[ $( apt-cache policy lm-sensors | grep "(ei mitään)" ) ]] && echo 'koneessasi ei ole pakettia nimeltä: lm-sensors . Haen sen' && sudo apt-get install "lm-sensors"
n=0
edellinen_tulos=0
while true; do
mittaus[$n]=$(sensors -Au | grep -Po '(?<=_input: ).*' | tail -$(nproc) | tr "\n" " " | awk 'END {for(i=1;i<=NF;i++) t+=$i; print t/NF}')
# mittaa kaikkien ytimien lämpötilat ja tulostaa niiden keskiarvon
[[ ${mittaus[n]} != $edellinen_tulos ]] && echo ${mittaus[n]} && edellinen_tulos=${mittaus[n]} && let n++
[[ $n == 10 ]] && echo ${mittaus[*]} | awk '{for(i=1;i<=NF;i++) t+=$i; printf "%s %2.1f", "keskiarvo: ",t/NF}' && break
done
**
Tässävaiheessa tulee tarve esittää mittaustulokset xy-käyrinä. Yksinkertainen alku on seuraavanlainen:
#!/bin/bash
# aluksi tarkistetaan onko koneessa tarvittava plotutils-ohjelma ja jos ei ole niin se ladataan
[[ $( apt-cache policy plotutils | grep "(ei mitään)" ) ]] && echo 'koneessasi ei ole pakettia nimeltä: plotutils . Haen sen' && sudo apt-get install "plotutils"
# ensin muodostetaan data-tiedosto jossa tiedot ovat muodossa: x0 y0 x1 y1 x2 y2 ...
# x-arvoissa jokaisen arvon tulee olla suurempi kuin edellinen x-arvo
echo 0.0 0.0 1.0 0.2 2.0 0.0 3.0 -0.4 4.0 0.2 5.0 0.6 > ~/abc
# seuraava käsky muodostaa datasta kippuran tiedostoon: ~/plot.ps
graph -T ps ~/abc > ~/plot.psA potential source of a full filesystem are large files left open but have been deleted. On Linux, a file may be deleted (removed/unlinked) while a process has it open. When this happens, the file is essentially invisible to other processes, but it still takes on physical space on the drive. Tools like du will not see it.
**
Seuraavaksi edelliset nivotaan yhteen. Skripti kuvaa reaaliaikaisesti prosessorin kaikkien ytimien lämpötilojen keskiarvon kehitystä graafisesti. X-akselilla ovat sekunnit ja y-akselilla asteet. Piirros skaalataan ja akselit merkitään automaattisesti. Ohjelman aikana voi ajaa samanaikaisesti jotain ohjelmaa joka kuormittaa prosessoria. Millä kuormitatkin niin laita kuormitus päälle ensiksi sillä tämän grafiikka-ohjelman keskeyttäminen on haastava tehtävä. Kirjoittaudu ulos jos et muuten saa skriptiä loppumaan.
grep -Pzo '(?s)(?<=begin).*(?=.*end)
Ohjelma toimii nytkähdellen ja epäilemättä ohjelma on muutenkin omituinen sillä en hallitse BASH:in graafisia toimintoja, esimerkiksi on minulle on täysin epäselvää mitä ohjelmaa kannattaisi käyttää.
- skripti on hiomaton jotta se olisi helpompi ymmärtää.
- äskettäinen 23.7.2015 päivitys muutti sensors-ohjelman toimintaa ja se vaati muutoksen tähänkin skriptiin.
#!/bin/bash
[[ $( apt-cache policy lm-sensors | grep -E '(ei mitään)|none)' ) ]] && echo 'koneessasi ei ole pakettia nimeltä: lm-sensors . Haen sen' && sudo apt-get install lm-sensors
[[ $( apt-cache policy plotutils | grep -E '(ei mitään)|(none)' ) ]] && echo 'koneessasi ei ole pakettia nimeltä: plotutils . Haen sen' && sudo apt-get install plotutils
[[ $( apt-cache policy gv | grep -E '(ei mitään)|(none)' ) ]] && echo 'koneessasi ei ole pakettia nimeltä: gv . Haen sen' && sudo apt-get install gv
n=0; echo "" >~/xy_arvot
while true; do
apu=$(sensors | grep -Po '(?<=Core [0-9]).*' | awk '{print $2}' | awk '{t+=$0} END {print t/NR}') # lasketaan kaikkien ytimien lämpötilojen keskiarvo - niin monta kuin niitä ytimiä onkin.
echo $(echo $n/60 | bc -l)' ' $apu >> ~/xy_arvot
graph -T ps ~/xy_arvot > ~/plot.ps; killall gv; gv ~/plot.ps &
let n+=2; sleep 2 # mittausten välillä noin 2 sekuntia - ajan suhteellinenkin arvo on melko merkityksetön
done
**
Tavallisella Live-muistitikulla voi taas päivittää salasanaa antamatta kaikki linuxit missä koneessa hyvänsä, vaikka siinä olisi EFI asennus eikä se edes boottaisi. Skripti ei siis ainoastaan päivitä vaan myös palauttaa boottaus-kyvyn.
- muuten UEFI testi: [[ -d /sys/firmware/efi ]] && echo 'kone käyttää UEFI:a' || echo 'kone ei käytä UEFI:a' .
- skripti löytyy paikasta:
http://forum.ubuntu-fi.org/index.php?topic=31223.msg241294#msg241294**
Teoriassa kone pitäisi päivittää aamun ensimmäisenä tehtävänä. Ja kehitysversio pitää päivittää monesti päivässä ellei halua uus-asentaa tilttiin mennyttä konetta. Mutta varusohjelmiston päivitys ei kelpaa, sillä se jättää oleellisia asioita tekemättä saavuttamatta ajallistakaan hyötyä.
Harkitsin taas kerran siirtymistä BTRFS:ään sillä päivitys-skripti toimii silläkin pienin muutoksin - ja olisihan tuo BTRFS:n snapshot myös sovellettavissa tähän nopeine epäonnistuneen päivityksen hylkäämisineen. Vaan ei se kumminkan auttaisi, sillä recovery-menusta taitaa puuttua kohta: boottaa siihen imageen joka viimeksi toimi. Mutta kieltämättä houkuttelee sillä ei se luultavasti olisi suurikaan työ.
**
Tästä on kyllä annettu tälläkin foorumilla hyvät ohjeet mutta esitetäänpä nyt asiat hieman toisin kuin ennen: aina kun systeemissä joku sovellu kaatuu kirjoitetaan siitä raportti ja annetaan käyttäjälle kaksi vaihtoehtoa: ohita ja:jatka raportti kehittäjille. Mutta tuo "ohita" valinta on salahauta: maailmantappiin jokakerran kun boottaat niin tuo kysymys esitetään uudestaan jos siitä ei ole kertaakaan raportoitu kehittäjille.
Onhan se pikkuisen nolo homma olla kertomatta kehittäjille että Ubuntusi on kaatunut - "käytät vain ilmaista Ubuntua mutta et edes viitsi auttaa kehittäjiä". Mutta monet ohjelmoijatkin käskevät kylmän tyynesti:
sudo rm /var/crash/*
jolloin vanhat raportit nollautuvat tai peräti: sudo gedit /etc/default/apport ja muuttamalla sillä ykkönen nollaksi jolloin raportteja ei enää ylipäätään muodostu.
Ja täytyy myöntää että minäkin syyllistyn moiseen. Koska tekeeköhän ne mitään periferiasta tulleille raporteille ?
**
Piti seurata pesukoneen tehonkulutusta ajan funktiona. Etsiskelin millaisia tiedonkeruu-laitteita Ubuntuun löytyy. Kalliitahan ne ovat ja niiden ubuntu-yhteensopivuus on niin ja näin. Mutta toisaalta: melkeinpä jokainen kone on äänitaajuusalueen oskilloskooppi käytettäessä pakettivarastossa olevaa xoscopea. Siitä en yrittänytkään selvittää kuinka työlästä on saada tarkkoja tuloksia, mutta halpaa se ainakin olisi. Xoscopen seuraava versio osaa muuten fourier-muunnoksen joten spektrinkin saisi.
Kerrotaanpa hieman xoscope:sta:
- bittisyys kuulemma riippuu äänikortista: useimmat äänikortit ovat 16-bittisiä. Äänikorttikin voi kuulemma olla DC-kytketty jolloin silloin saisi myös DC:n. 24-bittisellä äänikortilla siis saa paremman resoluution kuin ammatti-vehkeillä.
- herkkyyttä löytyy vielä yli 10* - siis herkempi kuin useat ammattivehkeet.
- käyttö on hankalaa vasta-alkajalle: esimerkiksi pyyhkäisynopeutta säädetään napeista 9 ja 0, triggausta napista + , herkkyyttä napeista { ja } - jos tarvitsee vaimennusta niin vaimentimen kyllä joutuu itekemään itse ...
- sisäänmeno on mikrofoni-sisäänmeno. Kaksikanavainenkin siis ryökäle, saisi mitattua cosini-fiin:kin. Esimerkkinä toistaiseksi vain "sormihurina" (kun mittapään elikä mikrofonisisäänmenon toisen kuuman tökkää sormensa): tulos on sellainen kuin odottaa sopiikin.
Kuva avautuu kun kirjoittaudut foorumille:
**
Joskus käyttäjä poistaa vahingossa itseltään sudo-oikeuden ja sudo-oikeuttahan ei käyttäjä itse voi silloin palauttaa koska sudo-oikeuden palauttaminen vaatii sudo-oikeutta. Sudo-oikeus voidaan palauttaa "live-CD:llä tai jollakin muulla sudo-oikeuden omaavalla" siirtymällä chroot:illa sudo-oikeuden menettäneen käyttäjän kovalevy-osiolle ja liittämällä käyttäjä sudo-ryhmään.
- joskus käyttäjä eroaa vahingossa myös jostain muustakin ryhmästä johon olisi syytä kuulua joten ne kannattaa kaikki palauttaa samallakertaa. Kaikki tapahtumat skriptin-pätkänä:
# varmistetaan että käyttäjä kuuluu kaikkiin niihin ryhmiin joihin hänet on liitetty asennettaessa. Huomaa ettei tämä poista mitään.
# käyttäjä liitetään Ubuntua asennettaessa seuraaviin ryhmiin: adm cdrom sudo dip plugdev lpadmin sambashare. Käyttäjä tulee liittää myös ryhmään jolla on käyttäjän nimi.
# käsky: $(echo ${0%} | tr "/" " " | awk '{print $(NF-2)}') kertoo minkä nimisen käyttäjän tiedostoissa ollaan.
for apu in adm cdrom sudo dip plugdev lpadmin sambashare $(echo ${0%} | tr "/" " " | awk '{print $(NF-2)}'); do
[[ ! $(groups | grep $apu) ]] && sudo addgroup $(echo ${0%} | tr "/" " " | awk '{print $(NF-2)}') $apu
done
**
Kun tekee käyttäjälle tarkoitettua skriptiä on syytä välttää sudo:n käyttämistä ellei se ole ihan pakko sillä ei ihmiset halua salasanaa kirjoittaa - kun ei käytä skriptiä niin eipähän tarvitse salasanaa kirjoitella ja onhan se pieni turvallisuusriskikin. Mutta toki sudo:n voi määrätä mikäli sudo on annettu jo aikaisemmin ja on A potential source of a full filesystem are large files left open but have been deleted. On Linux, a file may be deleted (removed/unlinked) while a process has it open. When this happens, the file is essentially invisible to other processes, but it still takes on physical space on the drive. Tools like du will not see it.edelleen voimassa.
Sen määrittely onko sudo vielä voimassa:
[[ $(sudo -n uptime 2>&1 | grep "load") ]] && echo 'sudo on vielä voimassa' || echo 'sudo ei ole voimassa'
**
Kovalevyn attribuuttien selville saamiseksi on lukemattomia konsteja. Niiden yhteinen piirre tuntuu olevan se, että ne vaativat sudo:a. Esimerkiksi käsky: blkid toimii näennäisesti ilman sudo:a, mutta lähemmin tarkasteltuna osottautuu että se vaatii sittenkin kunnolla toimiakseen sudo:a. Mutta toki konsti löytyy: otetaanpa esimerkiksi osiotyypin selvittäminen:
udevadm info -n /dev/sda1 -q property | grep -Po '(?<=ID_FS_TYPE=).*'
- ja samalla periaatteella saa muitakin attribuutteja
- tai viimeksi lisätyn USB-laitteen idProduct:idVendor:
echo $(journalctl | grep usb.*New.*idVendor= | tail -1 | grep -Po '(?<=idVendor=)[0-9A-Za-z]*')':'$(journalctl | grep usb.*New.*idVendor= | tail -1 | grep -Po '(?<=idProduct=)[0-9A-Za-z]*')
**
Koska levylle kirjoittaminen on hidasta niin kirjoittaminen suunnataan aina RAM:miin, tarkemmin sanoen buffereihin. Buffereista tuo tieto kirjoitetaan käyttöjärjestelmän toimesta aikanaan levylle mutta saattaa kestää muutaman minuutinkin ennenkuin kaikki on varmasti kirjoitettu levylle. Mikäli kone sammutetaan aikaisemmin niin buffereissa ollut tieto katoaa. Kun tehdään ohjelmaa niin sen kiireettömiin kohtiin voi kirjoittaa käskyn: sync joka tyhjentää buffereista kirjoitettavat levylle.
- tämän "kiireettömän" kohdan valinta on vaikeaa sillä väärään paikkaan kirjoitettuna se aiheuttaa ohjelmassa hidatelua.
- paljonko bufferoitua ja kenties levylle kirjoitettavaa on: grep ^Dirty /proc/meminfo
- ei sync-käsky teoriassa USB-muistitikulle riitä vaan lisäksi tarvitaan: umount .... ennenkuin sen voi irroittaa - helpompi irroittaa se nautiluksessa.
**
Luin netistä Linux-magazinea. Sikäli hyödyllinen homma että sain taas kertaalleen opastusta siitä kuinka BASH-skriptejä opetetaan tekemään väärin niidenkin toimesta joiden pitäisi tietää. Minkähän takia sillä kunnollisia BASH-virtuooseja on vielä jonkunverran? Jokatapauksessa opin senkin, että seuraava käyttäjälistan tulostus toimii ainakin Ubuntussa:
awk -F: '/home/&&/bash/ {print $1}' /etc/passwd
- muuten || on tai-funktio jos sitä tarvitset.
**
Ohjelmat muodostuvat joskus monesta itsenäisestä osasta joista joku/jotkut keräävät tietoa ja kirjoittavat sen jonnekin ja joku/jotkut lukevat sitä ja tulostavat sen sitten näytölle. Käsiohjauksella työ on yksinkertainen: ensin ajetaan ohjelma joka kerää tiedon ja kirjoittaa sen jonnekin ja kun se on lopettanut niin ajetaan ohjelma joka lukee niitä tietoja ja tulostaa ne näytölle. Mutta entäpä jos tuo tiedonkeruu voi alkaa joko hetikohta tai kuukauden kuluttua tai peräti pätkittäin? Tämä ongelma ratkeaa nimetyn-putken avulla. Toiminnan kuvaus yksinkertaisimmillaam:
Avaa ensimmäinen pääte (esimerkiksi painamalla ctrl-ALT-t) ja:
anna käsky: mkfifo NimettyPutki
anna käsky: echo hilipatarallaa > NimettyPutki # enterin painamisen jälkeen ei tapahdu enää mitään, edes uutta kehotetta ei tule
avaa toinen pääte (esimerkiksi painamalla ctrl-ALT-t) ja anna käsky: cat NimettyPutki
se tulostaa: hilipatarallaa
palaa ensimmäiseen päätteseen ja huomaat että se on tulostanut jälleen kehotteen.
- muodostuvaan NimettyPutki-nimiseen tiedostoon voi soveltaa kaikkia niitä toimia joita tiedostoon yleensäkin.
**
NimettyäPutkea voidaan käyttää esimerkiksi kun kaksi skriptiä toimivat eripitkään, mutta silti haluna olisi että ne toimisivat yhtämonta kertaa. Tämän aikaansaamiseksi nopeampi laitetaan odottaman hitaamman valmistumista. Kumpihyvänsä saa olla se hitaampi, tulostusjärjestys kylläkin muuttuu.
- tottakai BASH:issa on toisia parempiakin keinoja mutta onhan tämä yksi menetelmä.
Tee skripti nimeltä: skripti1
#!/bin/bash
rm -f NimettyPutki && mkfifo NimettyPutki
while true; do
Alkuhetki=$(date +%s.%N)
sleep 1 # sleep:in tilalle voi laittaa minkähyvänsä toiminnon ja sen kuluttama aika tulostuu
Loppuhetki=$(date +%s.%N)
echo -e 'skripti1:n suoritusaika: '$(echo $Loppuhetki-$Alkuhetki | bc -l)'\n' > NimettyPutki # skripti1 lukitsee itsensä
done
Tee toinen skripti nimeltä: skripti2
#!/bin/bash
while true; do
Alkuhetki=$(date +%s.%N)
sleep 10 # sleep:in tilalle voi laittaa minkähyvänsä toiminnon ja sen kuluttama aika tulostuu
Loppuhetki=$(date +%s.%N)
echo 'skripti2:n suoritusaika: '$(echo $Loppuhetki-$Alkuhetki | bc -l)
cat NimettyPutki # tämä vapauttaa skripti1:n
done
Toiminta:
Avaa pääte (paina ctrl-ALT-t) ja käske: . skripti1
Avaa toinen pääte (paina ctrl-ALT-t) ja käske: . skripti2
Alkaa tulostua noin kymmenen sekunnin välein jotain seuraavankaltaista:
skripti2:n suoritusaika: 10.005455598
skripti1:n suoritusaika: 1.005531242
skripti2:n suoritusaika: 10.005275533
skripti1:n suoritusaika: 1.004949491
**
Tutkin taas kerran kuinka tekstistä saa erotettua tagien välisen lohkon. Tapoja on lukemattomia ja todella erikoisia konsteja on vaikka minkälaisia. Muutamia yksinkertaisia:
grep -Pzo '(?s)begin.*end' # (?s) on ohje regex:älle siitä että . vastaa myös rivinsiirtoa.
grep -Pzo '(?s)(?<=begin).*(?=.*end) # tagien paikoilla on tyhjä rivi
sed -n '/begin/,/end+/ { p }' # kirjoita lohkojen väliin tyhjä rivi. Siis esimerkiksi: cat /boot/grub/grub.cfg | sed -n '/BEGIN/,/END+/ { p }'
awk '/BEGIN|begin|<</,/END|end|>>/ {print $0}' # | merkki on TAI
- myös regex:t sopii: lspci -v | awk '/VGA/,/^$/' # lohkon alku on VGA ja loppu tyhjä rivi
- tiedostoissa on joskus epäkelpoja merkkejä. Tällöin esimerkiksi:
cat /boot/grub/grub.cfg | tr -dc [[:graph:]]+'\n' | grep -Pzoi '(?sU)begin.*end' | sed "s/BEGIN/******* lohkon raja *******\nBEGIN/g"