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:

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

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ó:

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ó:

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:

  1. Comprovació de l'existència del fitxer: Test-Path -Path "El meu fitxer" # Retorna True si el fitxer existent

  2. Lectura del contingut del fitxer: Get-Content "El meu fitxer" # Llegeix tot el contingut del fitxer

  3. Eliminació d'un fitxer: Remove-Item "El meu fitxer" # Elimina el fitxer especificat

  4. Operacions de directori:

Powershell ofereix diversos cmdlets per gestionar directoris, com ara:

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" i Get-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