Ir al contenido

1. Introducció al scripting

Un administrador de sistemes que fa la mateixa tasca dos cops ja està perdent el temps: la tercera vegada l’ha d’haver escrit en un script. Esta pàgina és la base de tota la unitat: com s’escriu i s’executa un script, com es guarda informació en variables i com sap un script si una ordre ha anat bé o ha fallat.

Un script és un fitxer de text que conté una seqüència d’ordres. El shell (l’intèrpret d’ordres) les executa una darrere de l’altra, exactament com si les haguessis escrit tu a mà en la terminal. La diferència és que l’script es guarda, es pot repetir sense errors de teclejat i es pot programar perquè s’execute sol.

Treballarem dos shells en paral·lel, perquè un administrador professional es troba amb tots dos:

Bash PowerShell
Origen Shell per defecte de la majoria de distribucions Linux (i de macOS fins fa uns anys) Shell de Microsoft; Windows PowerShell 5.1 ve amb Windows i PowerShell 7 (pwsh) es pot instal·lar també en Linux i macOS
Què passa per les canonades Text Objectes (amb propietats i mètodes)
Extensió habitual .sh .ps1
Tipus de dades Quasi tot és text Tipus reals de .NET (enters, text, dates, arrays…)
Si hi ha una errada L’script continua si no ho impedixes Depén de l’errada; molts cmdlets continuen

Els exemples que veuràs ací estan escrits perquè funcionen tal com estan en un Linux amb Bash 4 o posterior i en Windows PowerShell 5.1. Quan veges una ordre amb sudo, o una consola de PowerShell «com a administrador», és perquè necessita privilegis.

Obri un editor (nano primer_script.sh) i escriu:

#!/bin/bash
# primer_script.sh · el primer script
echo "Hola, açò és un script en Bash"

La primera línia, #!/bin/bash, s’anomena shebang: diu al sistema quin intèrpret ha d’usar per a executar el fitxer. A partir d’ací, tot el que comença per # és un comentari que el shell ignora.

Per a executar-lo hi ha dues maneres:

Ventana de terminal
bash primer_script.sh # passa el fitxer a bash: no cal permís d'execució
chmod +x primer_script.sh # dona permís d'execució al fitxer
./primer_script.sh # l'executa directament (usa el shebang)

Tres coses que sorprenen la primera vegada:

  • Sense chmod +x, ./primer_script.sh respon Permission denied: el fitxer és text, no un programa, fins que li dónes el permís x.
  • Sense ./, el shell busca primer_script.sh només en les carpetes de la variable PATH. La carpeta actual no hi és (per seguretat), i obtens command not found. El ./ significa «el de la carpeta actual».
  • Sense shebang, si el llances des de Bash normalment també funciona, però el comportament depén de qui l’execute (un altre shell, cron…). Posa-hi sempre el shebang.

Escriu el fitxer primer_script.ps1:

Ventana de terminal
# primer_script.ps1 · el primer script
Write-Host "Hola, açò és un script en PowerShell"

S’executa des d’una consola de PowerShell escrivint-ne la ruta. Com en Bash, la carpeta actual no es busca automàticament, així que cal el .\:

Ventana de terminal
.\primer_script.ps1

Si no has fet res més, a Windows és molt probable que veges un error del tipus «no es pot carregar el fitxer perquè l’execució de scripts està deshabilitada en este sistema». No és una errada: és la política d’execució (Execution Policy), una mesura per a evitar que s’execute un .ps1 per descuit.

Política Què permet
Restricted Cap script (és la predeterminada als Windows de client)
AllSigned Només scripts signats digitalment per un editor de confiança
RemoteSigned Scripts propis sense signar; els descarregats d’Internet han d’anar signats
Bypass No bloqueja res i no avisa

Es consulta i es canvia així:

Ventana de terminal
Get-ExecutionPolicy -List
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

Dos matisos importants:

  • La política no és una barrera de seguretat, sinó una protecció contra errors. Qualsevol pot saltar-se-la per a un sol script amb powershell.exe -ExecutionPolicy Bypass -File script.ps1; ho farem servir quan programem tasques en la pàgina 3.
  • En PowerShell sobre Linux o macOS la política d’execució no s’aplica.

Una variable és un espai amb nom on l’script guarda un valor per a usar-lo més avant.

Concepte Bash PowerShell
Assignar nom="Ana" $nom = "Ana"
Llegir el valor echo "$nom" Write-Host $nom
Delimitar el nom echo "${nom}s" Write-Host "${nom}s"
Tipus Tot és text (l’aritmètica el converteix) Tipus reals: [int]$edat = 17
Variable d’entorn echo "$HOME" $env:USERPROFILE
Resultat d’una ordre data=$(date +%F) $data = Get-Date -Format "yyyy-MM-dd"

Per a llegir una variable en Bash cal el $ davant ($nom); per a assignar-la, no (nom=…). En PowerShell el $ va sempre.

Abans d’executar una línia, el shell la transforma: substituïx variables, executa ordres entre $( ), fa càlculs i separa el text en paraules. Entendre este pas explica la majoria dels errors. Les cometes decidixen què es transforma:

Escrius Bash i PowerShell fan…
'$nom' (cometes simples) Res: el text es queda tal qual, $nom
"$nom" (cometes dobles) Substituïx les variables: Ana
"avui és $(date +%F)" En Bash executa l’ordre de dins i posa la seua eixida. En PowerShell s’escriu "avui és $(Get-Date -Format yyyy-MM-dd)"
\$nom en Bash, `$nom en PowerShell Escapa el $: es mostra literalment

Amb nom="Ana", en Bash:

Ventana de terminal
echo '$nom' # $nom
echo "$nom" # Ana
echo "Hola $nom, avui és $(date +%F)"
echo "Costa 5\$" # Costa 5$

A més hi ha el partit de paraules (word splitting), la trampa clàssica de Bash. Una variable sense cometes es trenca en paraules pels espais:

Ventana de terminal
fitxer="Mi document.txt"
ls $fitxer # ls rep DOS arguments: «Mi» i «document.txt»
ls "$fitxer" # ls rep UN argument: «Mi document.txt»

Regla pràctica: en Bash, posa sempre les variables entre cometes dobles ("$variable") excepte quan vulgues expressament que es parteixen. PowerShell no té este problema: una variable és un valor, no text per a repartir.

Per a ensenyar-ho, el laboratori té la pestanya «Cometes i expansió»: escriu una línia i comprova en quines paraules es converteix abans d’executar-se.

En Bash, els càlculs es fan dins de $(( )) i només amb enters:

Ventana de terminal
a=7
b=2
suma=$((a + b)) # 9
quocient=$((a / b)) # 3 (divisió entera)
resta=$((a % b)) # 1 (residu)

PowerShell calcula directament i treballa amb decimals: 7 / 2 val 3.5.

Esta és una de les diferències que més confonen. En Bash, la condició va dins de [ ] i l’operador depén de si compares números o text:

Comparació Bash ([ ]) PowerShell
Números: igual, diferent -eq, -ne -eq, -ne
Números: major, menor, major o igual, menor o igual -gt, -lt, -ge, -le -gt, -lt, -ge, -le
Text: igual, diferent =, != -eq, -ne
Text buit / no buit -z "$x", -n "$x" [string]::IsNullOrEmpty($x)
«I», «o», «no» &&, ||, ! -and, -or, -not

Detalls que cal tindre presents:

  • En Bash els espais dins dels claudàtors són obligatoris: [ "$a" -gt "$b" ]. [$a -gt $b] falla perquè [ és una ordre i necessita espai després.
  • Usar -eq amb text en Bash dóna l’error integer expression expected. Usar = amb números compara com a text.
  • PowerShell no distingix majúscules en -eq ("Ana" -eq "ANA" és cert); per a distingir-les, -ceq.
  • En PowerShell, > no compara: redirigix l’eixida a un fitxer. $a -gt $b és la comparació.

7. Codis d’eixida: com sap un script si ha anat bé

Sección titulada «7. Codis d’eixida: com sap un script si ha anat bé»

Cada ordre, en acabar, torna al shell un número: el codi d’eixida (exit code). La convenció és:

  • 0 significa èxit.
  • Qualsevol altre valor (1, 2, 127…) indica un tipus d’error.

En Bash, l’ordre anterior deixa el seu codi en la variable especial $?:

Ventana de terminal
ls /etc > /dev/null
echo $? # 0: ha anat bé
ls /carpeta_inexistent 2> /dev/null
echo $? # 2: ls ha fallat
grep -q "root" /etc/passwd
echo $? # 0: s'ha trobat

Cada ordre sobreescriu $?. Per això este fragment amaga una trampa:

Ventana de terminal
mkdir /tmp/proves
mkdir /tmp/proves # falla: ja existix (codi 1)
echo "Intent fet" # echo acaba bé: ara $? val 0
echo $? # 0, no 1

Si necessites el codi d’una ordre, guarda’l immediatament: codi=$?.

Un script pot acabar amb el seu propi codi amb exit: exit 0 (tot bé) o exit 1 (hi ha hagut un error). Si no hi poses exit, el codi de l’script és el de l’última ordre executada. Qui el llance (un altre script, cron, el Programador de tasques) pot saber així si ha anat bé.

En PowerShell hi ha dos indicadors diferents:

Què és
$? True o False: si l’última instrucció ha anat bé
$LASTEXITCODE El número que ha tornat l’últim programa extern (ping, tar, robocopy…)

L’ordre exit 1 també funciona en un .ps1. En el laboratori, la pestanya «Traçador» et deixa seguir, línia a línia, com canvien les variables i $? mentre l’script s’executa: és la forma més ràpida d’entendre’ls.

  1. Escrius contador = 0 en un script Bash i obtens contador: command not found. Per què?

    Resposta

    Perquè en Bash no pot haver-hi espais al voltant del = en una assignació. El shell interpreta contador com una ordre amb dos arguments. S’escriu contador=0.

  2. Has creat neteja.sh amb el shebang correcte i executes ./neteja.sh: Permission denied. Què falta?

    Resposta

    El permís d’execució: chmod +x neteja.sh. Una alternativa sense permís és bash neteja.sh.

  3. Amb msg="Hola", què mostren echo '$msg' i echo "$msg"?

    Resposta

    La primera mostra literalment $msg (cometes simples: no hi ha expansió) i la segona mostra Hola.

  4. Estàs en una màquina de proves amb Windows i no tens permisos d’administrador. Quina ordre et deixa executar els teus propis scripts .ps1?

    Resposta

    Set-ExecutionPolicy RemoteSigned -Scope CurrentUser. Amb l’àmbit CurrentUser no cal ser administrador.

  5. Una ordre falla, després fas echo "fet" i després echo $?. Què mostra l’última?

    Resposta

    0. $? conté el codi de l’última ordre, que ha sigut l’echo "fet" (va bé). Per a conservar el codi de l’ordre que falla cal guardar-lo en una variable just després d’executar-la.

Valencià Castellano
script script, guion de órdenes
shell (intèrpret d’ordres) shell (intérprete de órdenes)
shebang shebang
permís d’execució permiso de ejecución
política d’execució (Execution Policy) política de ejecución
variable variable
cometes simples / dobles comillas simples / dobles
expansió expansión
partit de paraules (word splitting) división en palabras
codi d’eixida código de salida
comentari comentario
operador operador

Esta web no usa cookies ni recoge datos personales. Tu navegador solo guarda, en tu propio equipo, algunas preferencias: el tema claro u oscuro, el estado del menú y, en los laboratorios, la última pestaña abierta y el tamaño de letra.