Bash ma <(..)
do zastąpienia procesu. Jaki jest odpowiednik Powershell?
Wiem, że istnieje $(...)
, ale zwraca ciąg znaków, podczas gdy <(..)
zwraca plik, z którego zewnętrzne polecenie może odczytać, czego się spodziewa.
Nie szukam też rozwiązania opartego na potokach, ale coś, co mogę trzymać w środku wiersza poleceń.
powershell
ItdayD
źródło
źródło
Write-Output "The BITS service is $(Get-Service bits | select -ExpandProperty Stauts)"
aby uzyskać status usługi BITS bez uprzedniego załadowania jej do zmiennej. Patrząc na proces substytucji, nie jest to dokładnie to samo, ale wciąż może rozwiązać problem, przed którympsftp.exe
na transfery SFTP: jego-b
opcja wymaga, aby zapewnić poleceń uruchamiane na serwerze poprzez plik , który jest niewygodny, jeśli po prostu chcesz uruchomić, powiedzmymget *
. Gdyby PowerShell miał podstawianie procesów, byłbyś w stanie zrobić coś takiegopsftp.exe -l user -p password somehost -b <( "mget *" )
.Odpowiedzi:
Ta odpowiedź NIE jest dla Ciebie , jeśli:
- rzadko, jeśli w ogóle, potrzebujesz zewnętrznych interfejsów CLI (o co ogólnie warto starać się - komendy natywne PowerShell grają znacznie lepiej razem i nie potrzebują takiej funkcji).
- nie są zaznajomieni z podstawieniem procesu Basha.
Ta odpowiedź JEST dla Ciebie , jeśli:
- często korzystasz z zewnętrznych interfejsów CLI (czy to z przyzwyczajenia, czy z powodu braku (dobrych) alternatyw natywnych dla PowerShell), szczególnie podczas pisania skryptów.
- są przyzwyczajeni i doceniają to, co może zastąpić proces Bash.
- Aktualizacja : Teraz, gdy PowerShell jest także obsługiwany na platformach Unix, ta funkcja jest coraz bardziej interesująca - zobacz to żądanie funkcji na GitHub, co sugeruje, że PowerShell implementuje funkcję podobną do zastępowania procesów.
W świecie uniksowym, w Bash / Ksh / Zsh, podstawienie procesu oferuje traktowanie wyniku polecenia tak, jakby był to plik tymczasowy , który czyści się po sobie; np.
cat <(echo 'hello')
gdziecat
widzi wynikecho
polecenia jako ścieżkę pliku tymczasowego zawierającego wynik polecenia .Chociaż natywne polecenia programu PowerShell nie potrzebują takiej funkcji, może być przydatne podczas obsługi zewnętrznych interfejsów CLI .
Emulowanie funkcji w PowerShell jest uciążliwe , ale może być tego warte, jeśli często go potrzebujesz.
Wyobraź sobie funkcję o nazwie,
cf
która akceptuje blok skryptu, wykonuje blok i zapisuje dane wyjściowe w temp. plik tworzony na żądanie i zwraca temp. ścieżka pliku ; na przykład:To prosty przykład, który nie ilustruje dobrze potrzeby takiej funkcji. Być może bardziej przekonującym scenariuszem jest użycie
psftp.exe
do przesyłania SFTP: jego użycie wsadowe (zautomatyzowane) wymaga udostępnienia pliku wejściowego zawierającego pożądane polecenia, podczas gdy takie polecenia można łatwo utworzyć w postaci ciągu w locie.Aby być możliwie jak najbardziej kompatybilnym z zewnętrznymi narzędziami, temp. Plik powinien używać UTF-8 kodowanie bez BOM (znacznikiem kolejności bajtów) domyślnie, ale można poprosić o UTF-8 BOM się
-BOM
, w razie potrzeby.Niestety aspekt automatycznego czyszczenia zastępowania procesów nie może być bezpośrednio emulowany, dlatego konieczne jest jawne wywołanie czyszczenia ; czyszczenie odbywa się przez wywołanie
cf
bez argumentów :Do użytku interaktywnego można zautomatyzować czyszczenie, dodając wywołanie
prompt
funkcji czyszczenia do funkcji w następujący sposób (prompt
funkcja zwraca ciąg znaków zachęty , ale można jej także używać do wykonywania za sceną poleceń za każdym razem, gdy wyświetlany jest monit, podobnie jak polecenie Basha$PROMPT_COMMAND
zmienna); w celu zapewnienia dostępności w dowolnej sesji interaktywnej dodaj następujące oraz definicjęcf
poniżej do swojego profilu PowerShell:W przypadku użycia w skryptach , aby zapewnić wykonanie czyszczenia, blok, który używa
cf
- potencjalnie cały skrypt - musi być owinięty wtry
/finally
block, w którymcf
bez argumentów wywoływane jest czyszczenie:Oto implementacja : funkcja zaawansowana
ConvertTo-TempFile
i jej zwięzły aliascf
:Uwaga : Zastosowanie
New-Module
, które wymaga PSv3 +, do zdefiniowania funkcji za pomocą modułu dynamicznego zapewnia, że nie może wystąpić konflikt zmiennych między parametrami funkcji a zmiennymi, do których odwołuje się wewnątrz bloku skryptu.Zwróć uwagę na możliwość opcjonalnego określenia ścieżki wyjściowej [pliku] i / lub rozszerzenia nazwy pliku.
źródło
psftp.exe
, co skłoniło mnie do napisania tego. Mimo że lepiej jest robić wszystko natywnie w PowerShell, nie zawsze jest to możliwe; wywoływanie zewnętrznych interfejsów CLI z programu PowerShell powoduje i będzie miało miejsce; jeśli często masz do czynienia z interfejsami CLI, które wymagają wprowadzania plików, które można (bardziej) łatwo zbudować w pamięci / za pomocą innego polecenia, funkcja w tej odpowiedzi może ułatwić ci życie.Jeśli nie są ujęte w podwójny cudzysłów,
$(...)
zwraca obiekt PowerShell (a raczej to, co jest zwracane w dołączonym kodzie), najpierw oceniając załączony kod. Powinno to być odpowiednie do twoich celów („coś [I] może utknąć w środku wiersza poleceń”), zakładając, że wiersz poleceń to PowerShell.Możesz to przetestować
Get-Member
, przesyłając różne wersje , a nawet wysyłając bezpośrednio.Jak zauważyłeś, ujęte w podwójne cudzysłowy, „$ (...)” po prostu zwróci ciąg znaków.
W ten sposób, jeśli chcesz wstawić, powiedzmy, zawartość pliku bezpośrednio w linii, możesz użyć czegoś takiego:
źródło
Get-Content <(Get-ChildItem)
Get-ChildItem | Get-Content
działa idealnie? A może możesz spróbowaćGet-Content (Get-ChildItem).FullName
tego samego efektu? Być może podchodzisz do tego z perspektywy, na którą wpływa inne podejście skryptowe.