foreach valuefrompipeline
*EDITED
mały tutorial o przetwarzaniu przekazywanych wartości, który może radykalnie zmienić czas przetwarzania skryptu. wiadomka – pipelining jest podstawowym mechanizmem PS a przy przetwarzaniu wielu elementów, czasem wręcz odruchowo, wpisuje się '%’ czyli foreach-object. przykładowo – znajdź wszystkich, którzy mają nazwisko na 'x’ i wyślij im wiadomość:
get-aduser -filter 'surname -like "x*"' -properties mail|%{Send-MailMessage -To $_.mail -Body 'are you Asian?' -SmtpServer 10.10.10.10}
a teraz standardowy scenariusz z życia codziennego: dostajemy jakieś listy w postaci pliqw tekstowych. załóżmy, że są w nim nazwy kont, z którymi coś trzeba zrobić. szkielet jest trywialny:
cat .\list.txt|%{ do-something -name $_ }
…mija czas i okazuje się, że nasze 'do-something’ rozbudowaliśmy do postaci skryptu, ponieważ ilość wykonywanych czynności rośnie i oneliner jest zbyt mało wygodny. wartości można do skryptu przekazywać na dwa sposoby – bezpośrednio, jako parametr lub – tak jak powyżej – przez pipelining. druga metoda nie działa 'od ręki’, wymaga włączenia poprzez specjalny parametr: ’valueFromPipeline’ [lub valueFromPipelineByPropertyName… ale to na inny wpis].
żeby pokazać co się będzie działo załóżmy, że mamy listę komputerów i operacja wymaga uwierzytelnienia się do zdalnego zasobu:
do-something.ps1: param( [string[]]$identities ) $creds=get-credential foreach($id in $identities) { #tu skomplikowany kod Get-WmiObject -ComputerName $id -credential $creds -Class win32_computersystem }
w takim przypadq, aby uruchomić skrypt dla całej listy, należy przekazać listę przez parametr:
.\do-something.ps1 -identities (cat .\computerlist.txt)
polecenie w nawiasach '( )’ zostanie przetworzone, listing pliq zwraca tablicę stringów string[] i to zostanie przetworzone w skrypcie. jak na razie oczywiste oczywistości. nuda… ale zadanie nad którym pracujemy chcemy coraz bardziej automatyzować, cały proces do którego piszemy skrypty jest dość rozbudowany, a więc nasze skrypty muszą ze sobą gadać – output z jednego chcemy móc przekierować na kolejny. czyli trzeba włączyć pipelining:
do-something.ps1: [cmdletbinding()] param( [parameter(mandatory=$true,valueFromPipeline=$true,position=0)][string[]]$identities ) $creds=get-credential foreach($id in $identities) { Get-WmiObject -ComputerName $id -credential $creds -Class win32_computersystem write-host $id }
jeśli przekażemy wartości przez parametr tak, jak do tej pory, to nic się nie zmieni. ale jeśli przekażemy przez pipe … coś nie halo:
(1) cat .\computernames.txt|do-something.ps1
..wyświetli tylko dla ostatniego elementu /: [zwróć uwagę, że skrypt 'do-something’ wywołany jest bez parametru – valueFromPipeline oznacza 'jeśli potok wyjściowy jest przekierowany, przekaż go do tej zmiennej oznaczonej valueFromPipeline’ ]
ah! no oczywiście! zapomnieliśmy foreach:
(2) cat .\computernames.txt|%{do-something.ps1 $_ }
[tutaj już musi być parametr – $_ . a to dla tego, że nawiasy klamrowe '{ }’ definiują blok danych, separując potok od polecenia. niby niuans ale pokazuje, że totalnie zmienia się mechanika pod spodem]
hmm… no ale mamy kolejny problem – teraz skrypt przed każdym wywołaniem prosi o dane uwierzytelniające. lama poradzi sobie dodając parametr 'credential’ i przekazując go podczas wywołania. ale to nie jest zawsze dobry sposób i dobrze wiedzieć czemu tak się dzieje. błąd został popełniony w momencie dodania 'foreach’ (2). parametr 'identities’ w skrypcie został sprytnie zadeklarowany jako tablica, a więc powinien tablicę przyjąć. ale dodając 'foreach’, rozbijamy tablicę na poszczególne elementy i uruchamiamy skrypt wiele razy, przekazując każdą kolejną wartość jako parametr wywołania. a nie o to chodziło.
rozwiązaniem jest dodanie składni 'begin-process-end’ do skryptu. standardowo skrypt czeka na pojedynczą wartość, po dodaniu tego bloq tworzy 'pułapkę’ zawartą w bloq 'process’, która będzie się uruchamiać dla każdego kolejnego elementu. co więcej, 'process’ zostanie wykonany dla każdego przekazywanego elementu dokładnie tak, jak 'foreach’, a więc można się pozbyć tego fragmentu:
do-something.ps1 [cmdletbinding()] param( [parameter(mandatory=$true,valueFromPipeline=$true,position=0)][string[]]$identities ) begin { write-host 'begin' $creds=get-credential } process { #foreach($id in $identities) { <- już niepotrzebne write-host 'jakis text, zeby pokazac, ze zostanie wyswietlony FOREACH element' Get-WmiObject -ComputerName $identities -credential $creds -Class win32_computersystem write-host $identities #} <- juz niepotrzebne } end { write-host 'end.' }
teraz jeśli uruchomi się 'do-sthelse | do-something’ – zostaniemy zapytanie o credsy tylko raz, po czym wykonana zostanie część 'process’, a na koniec jednokrotnie wykona się klauzula 'end’. wyrzucam 'gwmi’ żeby pokazać przetwarzanie i zostawiam tylko write-host:
cat .\computerlist.txt | .\do-something.ps1 begin cmdlet Get-Credential at command pipeline position 1 Supply values for the following parameters: jakis text, zeby pokazac, ze zostanie wyswietlony FOREACH element name1 jakis text, zeby pokazac, ze zostanie wyswietlony FOREACH element name2 jakis text, zeby pokazac, ze zostanie wyswietlony FOREACH element name3 [...] jakis text, zeby pokazac, ze zostanie wyswietlony FOREACH element name1oo end.
o to chodziło.
co zapamiętać
czym innym jest przekazanie tablicy a czym innym kolejne przekazywanie parametrów tablicy – czyli foreach. jeśli skrypt jest duży, to można dużo oszczędzić. dla tego przy pokaźnych operacjach warto zajrzeć do pomocy, opisu parametrów skryptu i sprawdzić czy deklaracja:
- pozwala na przekazanie tablicy – np. [string[]]
- pozwala na przekazanie przez pipe – valueFromPipeline
ponadto trzeba pamiętać, że ponieważ 'valueFromPipeline’ jest pewnego rodzaju wskaźnikiem 'TU PRZEKIERUJ WSZYSTKO CO WPADA’ – to może być zadeklarowane tylko raz. zadeklarowanie wielokrotnie nie spowoduje błędu składniowego, skrypt uruchomi się, ale wyniki będą mocno niedeterministyczne…
eN.
przyszłość mediów streamingowych
kłamsTVo
dla mnie, jak i dla wielu moich znajomych, telewizja jest martwym medium. przyzwyczailiśmy się do 'żądania treści’ a nie przyswajania tego, co aqrat leci, czy czekania na konkretną godzinę. to takie naturalne – chcę coś obejrzeć, to siadam, otwieram przeglądarkę i włączam. Video on Demand – tak jak Internet jest z definicji 'na żądanie’. mnie od TV, obok konieczności dostosowania się do tego co aqrat jest, odstraszają przede wszystkim obrzydliwie długie bloki reklamowe. portale oferujące VoD rosną jak grzyby po deszczu, konqrując zarówno w ofercie biblioteki materiałów jak i samej wygody używania i aplikacji czy dostępności apki na coraz powszechniejsze SmatTV. i z jednej strony świetnie, że tak rozwija się ten rynek a wybór rośnie wraz z kolejnymi serwisami…
…ale każdy kij ma dwa końce. ile jesteś w stanie wymienić usług VoD? 5? 1o? a ile ich jest dostępnych? przejrzałem ranking popularności w Polsce i muszę przyznać, że jestem zaskoczony. owszem – nazwy top 1o to słyszałem, ale ich ranking mnie zdziwił… ale pominę tą kwestię, bo trzeba byłoby wgłębić się w to, jak liczone są odsłony i jakie treści w tych usługach, a nie to jest właściwym celem tego wpisu.
mam ochotę na… [teraźniejszość]
słyszałem o fajnym filmie/serialu/programie. chciałbym go obejrzeć. ha! ale gdzie? jeśli jest kilka kanałów dystrybucji, to można usiąść i sprawdzić czy dany materiał jest dostępny. ale w tym gąszczu dystrybutorów to niewykonalne. a więc z jednej strony mam 'wideo na żądanie’ ale z drugiej to nadal jest 'żądanie z wybranej, wąskiej grupy’. jak siadam do Internetu, to oczywiście chcę mieć dostęp do wszystkiego – rozwydrzyliśmy dzięki dobrym wyszukiwarkom.
bardzo pozytywnym sygnałem jest, że ludzie coraz chętniej są skłonni płacić a nie piracić. abonament za VoD zazwyczaj jest atrakcyjniejszy od kablówki… pod warunkiem, że zgadzamy się na bardzo ograniczoną bibliotekę. jeśli chcemy mieć dostęp np. do topowych seriali to okazuje się, że trzeba mieć abonament u kilkq dostawców, i nagle okazuje się, że to się już robią poważne kwoty. a więc jest lepiej ale nadal pozostają dwa podstawowe problemy – brak wyszukiwarki pozwalającej sprawdzić jaki dystrybutor posiada dany materiał, oraz sumaryczna kwota na dostęp. tymczasem posiadając jeden z wielu systemów Media Center [jak np. Kodi], wystarczy wklepać tytuł, zostanie wyszukany w jednym z wielu źródeł torrent czy usenet, ściągnie się, dopasuje napisy – i voila. przy odpowiedniej integracji wystarczy np. dodać tytuł do 'watchlist’ na IMDB czy innym serwisie, i wszystko zrobi się automatycznie. albo dodać newsfeed z ulubionymi serialami – po prostu będą czekać na naszym domowym urządzeniu do obejrzenia. póki co z nielegalnych źródeł.
podstawowym czynnikiem jest łatwość, wygoda i dostępność. za to można, i chce się, płacić. ale jeśli mam płacić i nadal mieć wymienione funkcje w ograniczonym zakresie podczas, gdy za darmo mogę mieć to wszystko bez ograniczeń?
streaming jutro
znów – nie jest celem tego wpisu dysqsja nad moralnością, a wyłącznie biznesowo-technicznie zastanowienie się nad tym, jak to zatem będzie wyglądało? bo będzie na pewno wyglądało inaczej. nie jestem jedyną osobą na świecie, która problem widzi, a jest masa osób, które takie spostrzeżenia potrafi przeqć na biznesplan [szkoda, że do nich nie należę /: ].
jeśli popatrzeć się na rozwój TV to wyglądało to podobnie – najpierw było niewiele kanałów i wielkie WOW. potem, wraz z rozwojem technologii, zaczęło pojawiać się coraz więcej dystrybutorów, i za kanały trzeba było płacić oddzielnie a nierzadko qpować dodatkowe dekodery. technologia satelitarna otworzyła rynek bardziej globalnie. aż w końcu, pojawiły się tzw. 'kablówki’ które agregują dostęp do wielu dystrybutorów w ramach pojedynczego abonamentu. zaczął się więc boom na dostawców – pamiętam, że jakieś 15 lat temu w niektórych miejscach Warszawy, można było przebierać w dostawcach TV niemal jak w samych kanałach. aż więksi zjedli mniejszych, i pozostało na rynq kilq największych graczy. oczywiście w przybliżeniu – wiadomo, że w skali mikro, jest wiele nisz, wypełnionych niszowymi firmami. ale trend jest widoczny i IMHO dokładnie to samo wkrótce stanie się z mediami VoD – zaczną powstawać abonamenty agregowane, oferujące w ramach pojedynczej opłaty dostęp do np. 5-6 różnych dostawców VoD. następnym krokiem będzie powstanie jakiś publicznych API pozwalających na przeszukanie bibliotek – bo w końcu każdemu dostawcy zależy na tym, żeby móc do niego dotrzeć, łatwiej dowiedzieć się 'HEJ, TO CZEGO SZUKASZ OBEJRZYSZ U MNIE’. w tej chwili każdy sobie. czemu więc nie ma powstać darmowa aplikacja, która potrafi przeszukać, powiedzmy, 5o dostawców VoD, wyświetlić wyniki, z ceną za wypożyczenie? a dostawca apki odetnie sobie bilecik. następnym krokiem po searchu będzie ustandaryzowanie dostępu do samej zawartości, dzięki czemu będą mogły powstawać playery [czy też, co bardziej prawdopodobne – obecne systemy Media Center], w których wklepiemy tytuł, wybierzemy filtr – czy to program dokumentalny, film, serial … tak jak [LoL] dziś wygląda to dla np. torrentów. player będzie miał wbite informacje o karcie kredytowej, oraz wyqpionych abonamentach, wystarczy kliknąć zgodę na cenę jeśli źródło będzie poza tym, i można oglądać. na końcu, firmy takie netflix, HBO GO, czy wg. rankingów najpopularniejsze w Polsce VoD.pl, player.pl, cda.pl itd – będą po prostu właścicielami bibliotek, a nad tym będą firmy oferujące boundle w zunifikowany sposób – tak jak dziś operatorzy kablówek, czy SAT…
zabawne jest to, że te nielegalne źródła są o eony bardziej przyjazne użytkownikowi już dziś. są niekwestionowanym wzorem tego, jak powinno to działać. tymczasem czeka nas jeszcze jakiś czas 'grzybów po deszczu’ i granulacji rynq, dziesiątki 'atrakcyjnych ofert’ z własną apką, własnym pomysłem, własną płatnością… i własną biblioteką [tak jak np. już zapowiadane odłączenie się Disney i utworzenie własnej apki]. oby jak najkrócej.
eN.