PowerShell: més enllà de la indicació!
Introducció
Powershell sovint veu eclipsat pel seu cosí Bash, però igual que Ruby, Powershell ofereix una profunditat que va més enllà de la impressió inicial.
Molts usuaris poden escriure un script amb Powershelldesprés de les interaccions bàsiques, però on destaca és quan les tasques es tornen complicades. Aquí, exploraré algunes raons per les quals Powershell excel·leix en escenaris de scripting complexos, fins i tot en comparació amb el popular Bash.
Tot i que Bash gestiona la majoria de les tasques del dia, la riquesa de Powershell es converteix en una fortalesa a mesura que els scripts són més implicats. Ens capbussarem en algunes característiques clau que fan de Powershell tan potent.
Cridar ordres externes
Powershell destaca com un llenguatge de scripting per la seva combinació única de capacitats de programació orientada a objectes (OOP) i shell. Aquesta convergència permet a PowerShell gestionar tasques complexes amb elegància i eficiència.
A diferència de Ruby o Python, que requereixen operadors especials com backticks (``) per executar ordres externes, PowerShell integra perfectament l'execució d'ordres a la seva sintaxi. Aquest enfocament simplificat no només simplifica l'escriptura, sinó que també millora la llegibilitat.
A més, la naturalesa OOP de PowerShell eleva les seves capacitats d'execució d'ordres. A diferència de Bash, que tracta les sortides d'ordres com a simples cadenes, PowerShell els percep com a Objectes. Aquesta distinció permet a PowerShell interactuar amb les sortides d'ordres d'una manera més significativa i dinàmica.
Per il·lustrar-nos el poder de l'execució d'ordres orientades a objectes de PowerShell, considereu l'exemple següent:
$Items = Get-ChildItem -Camí "/var/www/public"
Aquesta ordre recupera una llista de fitxers i directoris del camí especificat. A PowerShell, la sortida d'aquest ordre ($Items
) no és una cadena simple, és una col·lecció d'objectes, cada element representa un fitxer o directori.
Aquest enfocament orientat a objectes desbloquejats una gran quantitat de possibilitats. Per exemple, podeu filtrar fàcilment la sortida en funció de criteris específics, manipular les propietats dels elements recuperats o fins i tot canalitzar els objectes a altres cmdlets per a un processament posterior.
Les capacitats d'execució d'ordres orientades a objectes de PowerShell s'estenen més enllà de la mera recuperació de dades. També podeu executar ordres externes i interactuar amb les seves sortides com a objectes. Això us permet controlar de manera dinàmica el flux d'execució i els resultats del procés d'una manera més sofisticada.
Codi d'estat
Mentre que Ruby utilitza la variable $? per comprovar el codi de sortida de l'última ordre executada, de manera similar a Bash, Powershell ofereix un enfocament diferent.
A Powershell es crea de manera automàtica la variable $LastExitCode
que emmagatzema el codi de sortida de l'ordre anterior. Aquí teniu un exemple que demostra el seu ús:
# Successful command (exit code 0)
Get-Process
Write-Host "Last Exit Code: $($LastExitCode)" # Should output 0
# Failing command (non-zero exit code)
Get-Service -Name "NonExistingService"
Write-Host "Last Exit Code: $($LastExitCode)" # Non-zero exit code (specific value depends on the error)
És un shell dinàmicament tipat.
A diferència de Bash, que tracta tot com una cadena, Powershell adopta un enfocament de llenguatge escrit. Això millora la fiabilitat i el manteniment de l'script.
Tot i que Powershell no s'escriu estrictament com Java, utilitza un sistema de tipus dinàmic. Això significa que els tipus de variables són determinats en temps d'execució, però ofereixen capacitats de comprovació de tipus durant l'execució. Aquest equilibri proporciona flexibilitat sense comprometre la seguretat.
De manera semblant a la naturalesa orientada als objectes de Ruby, Powershell aprofita l'extensibilitat dels objectes. Això ens permet treballar amb dades d'una manera estructurada i significativa.
Aquí teniu un exemple que mostra com Powershell gestiona els tipus i els objectes:
# Get number of lines in a file (using Get-Content cmdlet)
$totalLines = Get-Content "my_file" | Measure-Object -Property LineCount | Select-Object -ExpandProperty Count
# Integer division (performs type conversion if needed)
$half = $totalLines / 2
# Print the first half of the file (using Select-Object for specific lines)
Get-Content "my_file" | Select-Object -Index 0..($half-1)
En aquest exemple:
Get-Content
retorna una col·lecció d'objectes que representa línies de fitxer.Mesure-Object
iSelect-Object
manipulen objectes per obtenir el recompte total de línies.- L'operador de divisió (/) realitza la conversió de tipus si és necessari (per exemple, convertint la representació de cadena del recompte de línies a un nombre enter).
Select-Object
amb indexació recupera la primera meitat de les línies com a objectes.
Enfocament funcional
Mentre que Ruby ofereix mètodes funcionals integrats com map
i select
, Powershell una funcionalitat similar mitjançant els seus cmdlets i el pipeline. Aquest enfocament de pipeline fomenta un estil únic de programació funcional dins dels scripts de Powershell. Vegeu un exemple:
Get-ChildItem | ForEach-Object { $_.Name.Trim().Length } | Write-Output
Get-ChildItem
: recupera una llista de fitxers i directoris.ForEach-Object
: itera per cada element de la sortida.$_.Name
: accedeix a la propietat name de l'element actual.Trim()
: elimina els espais en blanc inicials/finals del nom.Length
: obté la longitud del nom retallat (nombre sencer).Write-Output
: mostra les longituds calculades a la consola.
Com podeu veure, Powershell aprofita el pipeline i els cmdlets per aconseguir operacions funcionals. Aquest enfocament proporciona una manera clara i concisa de manipular les dades dins dels vostres scripts.
Expressions Regulars a Powershell
De manera similar a Ruby, Powershell ofereix un suport robust per a expressions regulars (regex) per a la concordança de patrons dins dels vostres scripts. A diferència de Ruby, on l'expressió regular és un tipus integrat, Powershell utilitza el mètode. Matches()
a les cadenes per efectuar operacions de concordança.
Aquí hi ha un exemple que demostra com aconseguir el mateix resultat que el fragment de codi Ruby mitjançant Powershell (centrant-se en la funcionalitat de regex, sense dependre d'ordres externs):
# Define the regex pattern to match branch name
$currentBranchRegex = "^\* (\S+)"
# Simulate output from a hypothetical "git branch" command
$outputLines = @("branch1", "* master", "branch2")
# Iterate through each line
$outputLines | ForEach-Object {
# Match the line with the regex pattern
if ($_ -match $currentBranchRegex) {
# Access the captured group (matched branch name)
$matchedBranch = $_.Matches[0].Groups[1].Value
Write-Host "Current branch: $matchedBranch"
}
}
Explicació:
$currentBranchRegex
defineix el patró d'expressió regular per capturar el nom de la branca després de l'asterisc (*).$outputLines
és una matriu que simula la sortida d'una hipotètica ordregit branch
.- El bucle
ForEach-Object
itera a través de cada línia de la matriu. - L'operador
-match
intenta fer coincidir la línia actual amb el patró d'expressió regular definit. - Si es troba una coincidència, l'expressió
$_.Matches[0].Groups[1].Value
recupera el grup capturat (el nom de la branca) de la primera coincidència. - Finalment,
Write-Host
mostra el nom de la branca capturada.
Aquest exemple mostra com Powershell aprofita el mètode Matches()
i captura grups dins d'expressions regulars per extreure informació específica de dades de text. Aquesta funcionalitat resulta valuosa per a diverses tasques com ara analitzar fitxers de registre, extreure dades del contingut web i validar l'entrada de l'usuari.
Nota: tot i que l'exemple utilitza una ordre hipotètica amb finalitats de demostració, Powershell pot interactuar amb eines externes com Git mitjançant el cmdlet Start-Process, la qual cosa us permet integrar la concordança d'expressions regulars amb les ordres de Git reals.
Threading a Powershell, un enfocament diferent
Tot i que Ruby ofereix un enfocament senzill de l'enfilament amb la classe Thread, Powershell utilitza un concepte anomenat Jobs per executar tasques simultàniament. Els treballs ofereixen una alternativa robusta i manejable per a operacions multiprocés.
Aquí teniu un exemple que demostra com aconseguir un resultat similar al fragment de codi Ruby mitjançant Powershell:
# Define the download URL template
$downloadUrlTemplate = "http://my_site.com/file_"
# Loop through file numbers (1 to 10)
1..10 | ForEach-Object {
$fileNumber = $_
# Start a new background job for each download
Start-Job -ScriptBlock { wget $downloadUrlTemplate + $fileNumber }
}
# Wait for all download jobs to complete
Wait-Job
# Optional: Check individual job results (if needed)
Get-Job
Explicació:
- L'script itera els números de fitxer (de l'1 al 10) mitjançant un bucle
ForEach-Object
. - Dins del bucle, el cmdlet
Start-Job
llança un nou treball de fons amb unScriptBlock
que conté l'ordre de descàrrega que inclou el número de fitxer actual. - El cmdlet
Wait-Job
posa en pausa l'script fins que s'acabin totes les tasques de descàrrega en segon pla. - Opcionalment, podeu utilitzar
Get-Job
per recuperar informació detallada sobre l'estat i els resultats de cada treball individual.
Aquest enfocament proporciona una manera estructurada de gestionar tasques concurrents a Powershell. Els treballs ofereixen funcions com ara la gestió d'errors, la cancel·lació de treballs i la recuperació de resultats, cosa que els converteix en una eina potent per gestionar operacions multiprocés als vostres scripts.
Gestió de fitxers i directoris a Powershell
De manera similar a les classes dedicades de Ruby per a operacions de fitxers i directoris, Powershell ofereix un conjunt de cmdlets dissenyats específics per interactuar amb el vostre sistema de fitxers. Aquest enfocament coherent simplifica els scripts i afavoreix la llegibilitat.
A diferència de Python, on les operacions de fitxers poden repartir entre diferents mòduls ( openper
llegir i os.remove
), Powershell
agrupa aquestes funcionalitats dins de cmdlets intuïtius.
Aquí teniu un desglossament de les operacions habituals de fitxers i directoris a Powershell:
Comprovació de l'existència del fitxer:
Test-Path -Path "El meu fitxer" # Retorna True si el fitxer existent
Lectura del contingut del fitxer:
Get-Content "El meu fitxer" # Llegeix tot el contingut del fitxer
Eliminació d'un fitxer:
Remove-Item "El meu fitxer" # Elimina el fitxer especificat
Operacions de directori:
Powershell ofereix diversos cmdlets per gestionar directoris, com ara:
Get-ChildItem
Llista els fitxers i directoris dins d'una ruta.New-Item
crea un fitxer o directori nou.Remove-Item
elimina un directori (utilitza-Recurse
per eliminar continguts de forma recursiva).Move-Item
mou o canvia el nom dels fitxers i directoris.
Nota: De manera similar a Ruby, els parèntesis al voltant dels arguments a Powershell solen ser opcionals tres que sigui necessari per a la claredat. Per exemple, ambdues
Get-Content "My File"
iGet-Content ("My File")
són ordres vàlides.
Conclusió
En conclusió, mentre que Bash segueix sent una opció popular per a les tasques bàsiques de scripting, PowerShell sorgeix amb una opció més potent per a escenaris complexos. La seva combinació única de funcions orientades a objectes i un enfocament racionalitzat per a l'execució d'ordres us permet escriure scripts clars, fàcils de mantenir i eficients. A més, PowerShell ofereix funcionalitats integrades per treballar amb tipus de dades, expressions regulars i multiprocés, característiques que rivalitzen amb idiomes com Ruby i Python. Aprofitant aquestes capacitats, PowerShell s'estableix com un llenguatge d'script versàtil que pot agilitzar l'administració del sistema i les tasques d'automatització.
Nota: Qualsevol cosa que vulguis discutir sobre aquest artícle, ho podem fer a Mastodon — Raúl