Plik, czyli zmienna.

VarZmienne w PowerShellu to dość ciekawy "zwierz". Większość użytkowników spotyka się z nimi w najprostszej postaci: $zmienna. Definiujemy, modyfikujemy, używamy. I tyle. Trzeba jednak wiedzieć, że zmienne to coś więcej niż tylko "worki" na nasze obiekty, do których odnosimy się wykorzystując tę najprostszą notację. W tym artykule postaram się wspomnieć o kilku sprawach związanych ze zmiennymi, które odróżniają zmienne w PowerShellu od zmiennych wykorzystywanych w innych językach programistycznych i skryptowych. Zanim jednak o tym, przyjrzymy się nieco dokładniej temu czym jest a czym nie jest w PowerShellu nazwa zmiennej.

Jak ci na imię?

Przede wszystkim pamiętać musimy o tym, że "$" nie jest częścią nazwy zmiennej. Nazwę stanowi wszystko to, co po tym symbolu się znajduje. Informacja szczególnie istotna, jeśli zamierzamy skorzystać z poleceń operujących na zmiennych (*-Variable), bądź parametrów, które nazwę zmiennych wykorzystując (-ErrorVariable, -OutputVariable, PipelineVariable). W każdym z tych przypadków operować będziemy na nazwach zmiennych, więc jeśli chcemy błędy zapisać w zmiennej $wpadka, to składnia prezentować się będzie następująco:

Get-Process -Id 13 -ErrorVariable wpadka -ErrorAction SilentlyContinue            
$wpadka.Exception

Druga istotna informacja o zmiennych: notacja dolar-nazwa to tak naprawdę skrótowiec. Pełny zapis zmiennej w wyrażeniach umożliwia nam bowiem definiowanie zmiennych o w zasadzie dowolnej nazwie. By jednak ze zmiennych o nazwach "egzotycznych" móc skorzystać, nazwę taką musimy otoczyć nawiasem klamrowym:

function Get-Prompt {            
    param (            
        [Parameter(            
            Mandatory = $true            
        )]            
        [String]${Podaj, proszę, nazwę pliku!}            
    )            
            
    ${Podaj, proszę, nazwę pliku!}            
}            
Get-Prompt
cmdlet Get-Prompt at command pipeline position 1
Supply values for the following parameters:
Podaj, proszę, nazwę pliku!:

Tu nazwa zmiennej (a raczej parametru funkcji), która stanowi pełne zdanie w języku polskim.

Dostawca dla zmiennych i…

W PowerShellu wiele zasobów oferowanych jest w formie dostawców. Dostawcy na ogół mają strukturę hierarchiczną (i do prezentowania danych o takiej strukturze były tworzone). Jest jednak kilku dostawców, które rodzą się i umierają z sesją PowerShella, a w których nie sposób odnaleźć strukturę drzewkową. Jeden z takich dostawców przeznaczony jest dla zmiennych.

Możemy więc wyświetlić zmienne zdefiniowane w aktualnym środowisku przy pomocy polecenia dir/ls – wielkie mi halo! Rzecz w tym, że to nie wszystko. Jeśli zechcemy zmienić nazwę zmiennej będziemy mogli skorzystać z polecenia Rename-Item:

Rename-Item -Path variable:\wpadka -NewName oops            
$oops

Jak pobrać zawartość zmiennej? Cóż, nazwa polecenia nasuwa się sama. Sprawdźmy jedynie czy polecenie zadziała zgodnie z naszymi oczekiwaniami. Dla odmiany jednak skorzystamy z aliasu:

cat Variable:\oops
Get-Process : Cannot find a process with the process identifier 13.(...)

I tu zaczyna się istny "Meksyk". Relacja jest bowiem dwustronna. Zmienne to obiekty w ramach dostawców, ale obiekty w ramach dostawców możemy traktować jak zmienne. Nic tak nie przemawia do wyobraźni jak przykład "z życia wzięty", spróbujmy więc dopisać coś do pliku hosts korzystając z tej cechy dostawców w PowerShellu:

${c:\windows\system32\drivers\etc\hosts} +=            
'127.0.0.1    powershell.pl'            
Test-Connection -ComputerName powershell.pl

Jak widać, tu właśnie szczególnie przyda nam się wspomniana na wstępnie składnia obejmująca nazwę zmiennej klamrami. Co jednak, gdy z klamr chcemy zrezygnować? Wystarczy wprzód zadbać o odpowiednią lokalizację w ramach wybranego dostawcy/dysku. Wówczas zamiast notacji "pełnej" wystarczy taka, która nazwę zmiennej poprzedzi nazwą dysku. Jest jedno ale: kropka (jakże często stosowana w nazwach plików…) jest jednym z symboli, które w nazwach zmiennych bez klamr nie są dozwolone. Szczęśliwie, plik hosts jest wyjątkiem od reguły. Zanim jednak dopiszemy kolejną linię do pliku stwórzmy jego kopię zapasową (z lenistwa, również bez rozszerzenia):

Push-Location C:\Windows\system32\drivers\etc            
$c:hostsbck = $c:hosts            
$c:hosts += '127.0.0.1 nowy.wpis.pl'            
Test-Connection -Count 1 -ComputerName nowy.wpis.pl

Na koniec wisienka na torcie: zamienimy treść obu plików miejscami. PowerShell oferuje taką możliwość w przypadku zmiennych, dlaczego więc pliki miałyby stanowić tu wyjątek? Jedna linijka kodu i już hostsbck zawiera nowy.wpis.pl a plik hosts jest od niego wolny:

$c:hosts, $c:hostsbck = $c:hostsbck, $c:hosts            
Get-ChildItem | Where-Object {            
    Select-String -Pattern nowy -Path $_.FullName            
}            

Co ciekawe: podobne możliwości oferuje dostawca dla funkcji czy aliasów. Działać to powinno dla każdego dostawcy, który rozumie koncept "zawartości", jeśli więc działa gdzieś Get-Content, notacja przeznaczona dla zmiennych również działać powinna.

~ - autor: Bartek Bielawski w dniu 17 stycznia, 2016.

Jedna odpowiedź to “Plik, czyli zmienna.”

  1. […] mamy dwie: polecenie Set-Content, lub składnia wykorzystująca zapis typowy dla zmiennych (pisałem o takim wykorzystaniu tej składni niedawno). To co mi osobiście podoba się w metodzie wykorzystującej atrybut to fakt, że definicja taka […]

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj /  Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj /  Zmień )

Połączenie z %s

 
%d blogerów lubi to: