Unix-komentotulkeissa kuten Bashissa on ollut vuosikaudet varsin monipuoliset tavat palata komentotulkin historiasta löytyviin komentoihin. Nuoli ylös palaa komentohistoriassa taaksepäin ja nuoli alas vie eteenpäin. Koko historian näkee komennolla "history":

$ history
 1257 git remote -v
 1258 cd /tmp/
 --- snip ---
 2242 id -un 0
 2243 id -gn 0

Tämän voi yhdistää grepin kanssa:

$ history|grep remote
 1264 git remote -v
 --- snip --

Yksi kätevimmistä on haku historiasta: ensin painetaan Ctrl-R ja sen jälkeen syötetään hakusana (alla "gpg"):

(reverse-i-search)`gpg': gpg -v --verify openvpn-2.4.6.tar.xz.asc

Mikäli järkevän oloinen komento löytyy, ajetaan se Return-näppäimellä. Jos komentoa halutaan muokata ajamatta sitä, painetaan Tab. Jos halutaan etsiä muita osumia, painetaan Ctrl-R uudelleen. Ctrl-R on erityisen kätevä silloin, kun on rakennettu rakkaudella valtavan pitkä komentorivi, joka on liian kaukana komentotulkin historiassa nuolinäppäimillä löydettäväksi.

Myös Powershellissä on mahdollista käyttää nuolinäppäimiä Bashin tapaan. Myös history-komento löytyy:

PS> Get-History 
 
 Id CommandLine
 -- -----------
 
 1 cd $HOME
 2 Get-ChildItem -Recurse
 3 cd opt
 --- snip --- 
 
 PS> Get-History | Where-Object { $_.CommandLine -like "*HOME*" } 
 
 Id CommandLine
 -- -----------
 
 1 cd $HOME

Historiasta haku onnistuu myös kirjoittamalla # ja syöttämällä hakusana...

PS> #history

... ja painalla Tab:

PS> Get-History | Where-Object { $_.CommandLine -like "*HOME*" }

Tab-näppäimellä voi etsiä muita osumia ja Return-näppäimellä valitaan tämänhetkinen komentorivi.

Toisinaan tulee tarpeelliseksi etsiä yhdestä tai useammasta tiedostosta jotakin merkkijonoa ja tulostaa täsmäävä rivi sekä tiedosto, jossa se on, sekä rivinumero. GNU grepillä tämä onnistuu triviaalisti komennolla "grep -HN <pattern>":

$ grep -Hn REXML *.rb
 group_policy.rb:71: dFile = REXML::Document.new( File.new("#{dDir}\#{array[0][0]}.admx"))
 group_policy.rb:72: eFile = REXML::Document.new( File.new("#{eDir}\#{array[0][0]}.adml"))
 group_policy.rb:154: dFile = REXML::Document.new( File.new("#{dDir}\#{sys_tShort}.admx"))
 group_policy.rb:155: eFile = REXML::Document.new( File.new("#{eDir}\#{sys_tShort}.adml"))
 group_policy.rb:428: dFile = REXML::Document.new( File.new("#{dDir}\#{tShort}.admx"))
 group_policy.rb:429: eFile = REXML::Document.new( File.new("#{dDir}\#{adml}"))

Sama homma onnistuu myös Powershellissä, mutta hieman vaikeammin:

> Get-ChildItem . -include "*.rb" -Recurse|Select-String -Pattern "REXML"
 group_policy.rb:71: dFile = REXML::Document.new( File.new("#{dDir}\#{array[0][0]}.admx"))
 group_policy.rb:72: eFile = REXML::Document.new( File.new("#{eDir}\#{array[0][0]}.adml"))
 group_policy.rb:154: dFile = REXML::Document.new( File.new("#{dDir}\#{sys_tShort}.admx"))
 group_policy.rb:155: eFile = REXML::Document.new( File.new("#{eDir}\#{sys_tShort}.adml"))
 group_policy.rb:428: dFile = REXML::Document.new( File.new("#{dDir}\#{tShort}.admx"))
 group_policy.rb:429: eFile = REXML::Document.new( File.new("#{dDir}\#{adml}"))

Powershelliä UNIX-ylläpitäjille -artikkelisarjan muut osat:

Tietyn nimisten tiedostojen (tai tyyppisten) poistaminen hakemistosta on melko suoraviivaista GNU findilla:

$ ls
 README.txt stderr.log stdout.log
 $ find . -maxdepth 1 -type f -name "*.log" -exec rm -f {} +
 $ ls
 README.txt

Valinta "maxdepth 1" estää findia poistamasta tiedostoja mahdollisista alihakemistoista.

Toinen vaihtoehto on putkittaa tiedostolistaus xargsille:

$ ls
 README.txt stderr.log stdout.log
 $ ls *.log|xargs rm -f
 $ ls
 README.txt

Tässä ei kuitenkaan erotella toisistaan tiedostoja ja hakemistoja, joten myös mahdolliset .log -päätteiset hakemistot yrittäisiin poistaa siinä epäonnistuen.

Powershell-ratkaisussa yhdistetään molempia lähestymistapoja:

> Get-ChildItem . -File|Select Name
 
 Name
 ----
 stderr.log
 stdout.log
 README.txt
 
 > Get-ChildItem . -File -Filter "*.log"|Remove-Item
 
 > Get-ChildItem . -File|Select Name
 
 Name
 ----
 README.txt

Parametri -File näyttää hakemistosta vain tiedostot, ei hakemistoja. Jos haluttaisiin poistaa myös alihakemistoista mahdollisesti löytyvät tiedostot, pitäisi Get-ChildItemille antaa parametri -Recurse. Komento Select Name on mukana vain tulosteen selkeyttämiseksi.

Powershelliä UNIX-ylläpitäjille -artikkelisarjan muut osat:

Tulosteiden uudelleenohjaus ja paluuarvojen käsittely toimii lähes samoin *NIX-shelleissä ja Windowsin Powershellissä. Alla tarkistetaan Linuxin systemctl-komennolla olemassa olevan ("openvpn") ja olemattoman ("fake") palvelun tila, ohjataan sekä tuloste että virhetuloste bittitaivaaseen ja tulostetaan komennon paluuarvo:

$ systemctl status openvpn > /dev/null 2>&1
 $ echo $?
 0
 $ systemctl status fake > /dev/null 2>&1
 $ echo $?
 3

Kuten näkyy, paluuarvo on 0 jos palvelu on olemassa ja 3 jos sitä ei löydy.

Powershell toimii käytännössä identtisesti (alla käytössä NSSM):

> nssm.exe status openvpn > $null 2>&1
 > Write-Host $LastExitCode
 0
 > nssm.exe status fake > $null 2>&1
 > Write-Host $LastExitCode
 3

Myös Powershellissä voitaisiin käyttää muuttujaa $?, mutta se ei sisällä numeerista paluuarvoa vaan totuusarvon:

> nssm.exe status openvpn > $null 2>&1
 > Write-Host $?
 True
 > nssm.exe status fake > $null 2>&1
 > Write-Host $?
 False

Sekä *NIX-shelleissä että Powershellissä voisi tulostevirrat ohjata myös vaihtoehtoisella tavalla:

$ systemctl status openvpn > /dev/null 2> /dev/null
 > nssm.exe status openvpn > $null 2> $null

Powershelliä UNIX-ylläpitäjille -artikkelisarjan muut osat:

Powershelliä konffatessa on tullut taas törmättyä useisiin varsin käyttökelpoisiin komentoihin. Alla ei-kattava lista, sillä lisää on luvassa sopivalla hetkellä.

Hakemiston poistaminen rekursiivisesti:

$ rm -rf <hakemisto>
 > Remove-Item -Recurse -Path <hakemisto>

Tiedoston viimeisten rivien näyttäminen:

$ cat <tiedosto>|tail -n <rivien_määrä>
 > Get-Content <tiedosto> -Last <rivien_määrä>

Tiedoston ensimmäisten rivien näyttäminen

$ cat <tiedosto>|head -n <rivien_määrä>
 > Get-Content <tiedosto> -First <rivien_määrä>

Tiedoston rivien määrän laskeminen:

$ cat <tiedosto>|wc --lines
 > Get-Content <tiedosto>|Measure-Object -Line

Powershelliä UNIX-ylläpitäjille -artikkelisarjan muut osat:

Alla on varsin hyvä vertailu Bashin ja Powershellin komennoista englanniksi (EDIT: sivu on sittemmin valitettavasti poistunut):

Kuten näkyy, Powershellissä on valmiina melko suuri määrä UNIX-tyyppisiä komentojen aliaksia. Aliakset viittaavat kuitenkin Powershell-komentoihin, joten esimerkiksi niiden valitsimet poikkeavat merkittävästi UNIX-komentojen vastaavista.

Powershelliä UNIX-ylläpitäjille -artikkelisarjan muut osat:

Windows-työasemien ja -palvelinten ylläpidosta voi tehdä huomattavasti tehokkaampaa ja hauskempaa Windows Powershellillä. Aiempaan Windowsin komentoriviin (cmd.exe) verrattuna Powershell on varsin ylivoimainen. Tietyt toimet ovat Powershellissä jopa helpompia kuin Unixin komentorivissä kuten Bashissa.

Powershellissä käsitellään tekstirivien tai binääridatan sijaan objekteja. joita voidaan putkittaa komennolta toiselle. Objektien käsittely on usein huomattavasti yksinkertaisempaa kuin tekstin, koska komennoissa voidaan viitata objektien ominaisuuksiin, eikä syötettä tarvitse UNIX:in komentorivien tapaan ensin siistiä ja pilkkoa lukuisilla komennoilla (esim. sed, cut, tr ja awk) oleellisen tiedon erottelemiseksi.

Tässä blogisarjassa käydään läpi Powershelliä nimenomaan UNIX-ylläpitäjän näkökulmasta pääosin lyhyiden esimerkkien avulla. UNIX-komentorivin kehote on lyhennetty selvyyden vuoksi hieman epätyypillisesti muotoon "$" ja Powershellin muotoon ">". Esimerkkikomennot eivät ole välttämättä kaikista optimoiduimpia, vaan tavoitteena on ollut pitää UNIX:in ja Powershellin komennot mahdollisimman samankaltaisina. UNIX-komennot toimivat sellaisenaan GNU-työkaluja käyttävissä käyttöjärjestelmissä, esimerkiksi Linuxissa.

(Teksti)tiedoston sisällön näyttäminen:

$ cat <tiedostonimi>
 
 > Get-Content <tiedostonimi>

Tiedoston etsiminen nimen perusteella:

$ find . -name "*teksti*"
 
 > Get-ChildItem . -Filter "*teksti*" -Recurse

Tiedostojen listaaminen:

$ ls -l
 
 > Get-ChildItem
 
 > dir

Tekstin etsiminen tiedostosta:

$ cat tiedosto|grep teksti
 
 > Get-Content tiedosto|Select-String -Pattern "*teksti*"

Ohjeiden hakeminen:

$ man komento
 
 > Get-Help komento

Tekstin tulostaminen komentoriville:

$ echo "Tämä on lause."
 
 > Write-Host "Tämä on lause."

Powershelliä UNIX-ylläpitäjille -artikkelisarjan muut osat:

menucross-circle