Scripts en bash i en Python

Creació i execució d'un script (bash)

Un script s'emmagatzema en un fitxer que normalment acaba amb l'extensió sh. La primera línia del script indica quin llenguatge shell s'està utilitzan (sh, bash, ...) . Aquesta línia comença amb els dos caràcters #! coneguts amb el nom de "Shebang" i després s'adjunta la ruta a l'intèrpret a utilitzar per a la seva execució. Tot i que es poden utilitzar diferents intèrprets bash és l'únic intèrpret considerat vàlid per a executables. Es pot utilitzar sh per a petites utilitats.
A continuació del Shebang s'inclouen la resta d'instruccions del programa. Podem afegir comentaris en qualsevol lloc , a partir de la línia 2 , del nostre fitxer utilitzant el símbol #

#!/bin/bash 
# Fitxer: script1.sh 
# Autor: Miquel Boada 
echo "Hello World, again!"    # Visualitza text per stdout

Un script o un programa interpretat en Linux es pot executar de múltiples formes. La forma més bàsica és indicant el nom del programa després del intèrpret de comandes que volem utilitzar. Per exemple:

bash script1.sh

Per la resta de sistemes d'execució cal establir permisos d'execució en el nostre programa. Una vegada assignats els permisos d'execució podem executar el nostre programa utilitzant una ruta relativa ( ./) o una ruta absoluta ( / ).
Una última opció consisteix , si l'usuari disposa de permisos suficients, en copiar els fitxers en algun dels directoris "bin" del sistema Linux. Aquesta última opció permet que el nostre programa estigui disponible des de qualsevol carpeta del sistema i el puguem referenciar directament utilitzant només el seu nom.
En aquest últim cas, el sistema buscarà el nostre programa en cada un dels directoris de la nostra variable d'entorn PATH fins a localitzar un fitxer executable amb el nom indicat. Si el mateix nom de fitxer apareix en diferents directoris, s'executarà el fitxer del primer directori de la variable PATH.
Podem visualitzar el contingut de la variable PATH amb la instrucció "echo $PATH" . Cada un dels directoris està separat mitjançant el símbol ":"
Imatge 1
En el següent enllaç es pot visualitzar un video amb els diferents sistemes d'execució d'un script en Linux:
Vídeo - Creació i execució d'un script en Linux utilitzant bash

Creació i execució d'un script (Python)

L'execució d'un programa o script en Python és molt semblant a la de bash script. Utilitzem el programa intèrpret (python3, python3.5, ...) segons la versió de Python que volguem utilitzar i a continuació indiquem el nom del fitxer que conté les instruccions. Cal tenir en compte que en Python tots els fitxers tenen com a extensió .py tot i que es permeten variants a aquesta extensió.
Si en bash s'utilitzava com a primera instrucció "#!/bin/bash" , en els programes de Python s'utilitzarà l'expresió "#!/usr/bin/env python3" . Tot i que es podria utilitzar l'expresió "#!/usr/bin/python3" aquesta és menys portable ja que limita l'ubicació del intèrpret de python3 al directori especificat. En els dos casos utilitzem el símbol Shebang (#!) per a especificar l'intèrpret a utilitzar per a l'execució del programa.

#!/usr/bin/python3
# L'expressió "#!/usr/bin/python3" limita la portabilitat
# print("Hello World!")

Exemple del mateix script però amb major portabilitat

#!/usr/bin/env python3
# L'expressió "#!/usr/bin/env python3" augmenta la portabilitat
# print("Hello World!")

A continuació del Shebang s'inclouen la resta d'instruccions del programa. Podem afegir comentaris en qualsevol lloc , a partir de la línia 2 , del nostre fitxer utilitzant el símbol #
Per executar el programa de Python sense necessitat de referenciar a l'intèrpret Python en la nostra línia de comandes, hem d'associar permisos d'execució al fitxer .py (fitxer que conté les instruccions). Una vegada assignats els permisos, podem executar el programa utilitzant una ruta relativa ( ./) o una ruta absoluta ( / ).
Una última opció consisteix , si l'usuari disposa de permisos suficients, en copiar els fitxers en algun dels directoris "bin" del sistema Linux. Aquesta última opció permet que el nostre programa estigui disponible des de qualsevol carpeta del sistema i el puguem referenciar directament utilitzant només el seu nom.
En aquest últim cas, el sistema buscarà el nostre programa en cada un dels directoris de la nostra variable d'entorn PATH fins a localitzar un fitxer executable amb el nom indicat. Si el mateix nom de fitxer apareix en diferents directoris, s'executarà el fitxer del primer directori de la variable PATH.
Podem visualitzar el contingut de la variable PATH amb la instrucció "echo $PATH" . Cada un dels directoris està separat mitjançant el símbol ":"
Imatge 2
En el següent enllaç es pot visualitzar un video amb els diferents sistemes d'execució d'un programa Python en Linux:
Vídeo - Creació i execució d'un script en Python
Nota: En aquest document s'utilitzarà la versió de Python 3 per a la realització de tots els exemples.

Bash - Variables

Definició de variables

En els nostres scripts és precís emmagatzemar informació que podem necessitar posteriorment per a la seva visualització , per a la realització de càlculs ... Per a guardar la informació precisem de variables. Una variable no és res més que un nom (normalment relacionat amb la informació que conté) on s'emmagatzema un determinat valor. Per assignar variables utilitzem el símbol de '='.

#!/bin/bash 
numero=10
lletra='a'
paraula_c_s='hola'
paraula_c_d="adeu"
frase_c_s='Avui no plou'
frase_c_d="Avui fa un bon dia"

És important no deixar cap espai entre el nom de la variable, el símbol d'igual (=) i el valor que es vol assignar.
Tal i com es pot comprovar en el codi anterior, es poden utilitzar cometes simples (') o cometes dobles (") per assignar els valors a les variables. Tot i que en aquest cas l'utilització és equivalent no sempre és així. Més endavant s'explicarà la diferència entre les cometes dobles i simples.

Denominació de les variables

Les variables començaran sempre per una lletra i podran contenir números, lletres i alguns símbols especials. Les regles de bon estil determinen
Utilitzar només lletres en minúscula. Si una variable està formada per diferents paraules, utilitzar '_' (subratllat) com a separador.

Exemples

#!/bin/bash 
edat=35              # conforme
edat_mitjana=20      # conforme 
edatMaxima=45        # No conforme a les regles de bon estil

Accedir a les variables

Guardar informació en el nostre programa no té sentit si no la podem recuperar. Per a recuperar el valor d'una variable ho podem fer incloent el símbol $ davant del nom de la variable.

#!/bin/bash 
# exemple accés variable NO Recomanat
edat=35              
echo "$edat"

Tot i que l'exemple anterior és correcte, no és el recomanat en la programació en bash script. La notació recomanada és una mica més complexe i inclou l'especificació entre claus de la variable.

#!/bin/bash 
# exemple accés variable recomanat
edat=35              
echo "${edat}"

Nota: Utilitzarem la notació $nom_variable si s'està modificant un programa on les referències de les variables ja utilitzen aquesta notació. Aquesta mesura és únicament per aconseguir una major coherència en el script que ajudi també a la seva coherència.

Tipus variables

El llenguatge bash permet una definició molt bàsica de variables mitjançant la directiva "declare" . Així, per exemple, el següent codi declara una variable entera i visualitza el seu contingut

#!/bin/bash 
declare -i edat=35              
echo "${edat}"

Utilitzarem la declaració de variables quan els programes siguin llargs i la declaració de les variables ajudi a la seva comprensió. En alguns casos, com es veurà més endavant, pot ajudar també a facilitar algunes operacions.
Més informació sobre declare: http://tldp.org/LDP/abs/html/declareref.html
L'intèrpret bash considera totes les variables de tipus string. Ho podem comprovar amb un simple programa.

#!/bin/bash 
objectiu=50
assolit=60
resultat=${assolit}-${objectiu}
echo "$resultat"

El programa anterior mostra per pantalla 60-50 ja que concatena el valor de les dues variables amb el guió (-)
Si es declaren les variables amb el seu tipus, l'operació es realitza de forma correcte.

#!/bin/bash 
declare -i objectiu=50 # -i per valor integer
declare -i assolit=60
declare -i resultat=${assolit}-${objectiu}
echo "$resultat"

En el següent video es mostra el funcionament dels dos programes anteriors: amb les variables declarades i sense declarar.
Declarant variables en Linux - part 1

Python - Variables

Definició de variables

En els nostres scripts és precís emmagatzemar informació que podem necessitar posteriorment per a la seva visualització , per a la realització de càlculs ... Per a guardar la informació precisem de variables. Una variable no és res més que un nom (normalment relacionat amb la informació que conté) on s'emmagatzema un determinat valor. Per assignar variables utilitzem el símbol de '='.

Denominació de les variables

Les variables començaran sempre per una lletra i podran contenir números, lletres i alguns símbols especials. Les regles de bon estil determinen
Utilitzar només lletres en minúscula. Si una variable està formada per diferents paraules, utilitzar '_' (subratllat) com a separador.

Exemples

#!/usr/bin/env python3
edat=35              # conforme
edat_mitjana=20      # conforme 
edatMaxima=45        # No conforme a les regles de bon estil

Accedir a les variables

Amb Python podem accedir als valors de les variables directament utilitzant el seu nom. A diferència de bash no hi ha diferència en la referència de la variable quan se l'hi assigna un valor o quan s'accedeix al valor emmagatzemat.

#!/usr/bin/env python3
edat=35              
print(edat)

Tipus variables

En Python els tipus de les variables és automàtica: no cal declarar de quin tipus és la variable, sinó que el tipus dependrà del valor que se li assigni.

#!/usr/bin/env python3
objectiu=1000 # variable de tipus enter  
actual=950.34 # variable de tipus real
text="Restant per assolir l'objectiu:"
resultat = actual-objectiu # variable de tipus real  
print(text,resultat)

Nota: en Python hem de vigilar quan es fan càlculs amb números reals, ja que utilitza la representació float. El resultat de les operacions amb float tenen problemes amb l'exactitud. Per tant, cal convertir els tipus float a decimal i establir la precisió que es vol obtenir en el càlcul. Per a més informació: Video - Python: operacions amb float

Escrivint informació en bash

És habitual que els nostres programes precisin visualitzar informació per pantalla, en un fitxer ... Per fer-ho disposem de la comanda "echo" . Aquesta comanda visualitza la informació en el dispositiu de sortida (pantalla , fitxer ...). Cada instrucció echo provoca un salt de línia després de la visualització de la informació. Per tant, si volem escriure un missatge en dues línies podem executar dues instruccions echo. Una alternativa és la d'utilitzar l'argument -e conjuntament amb la comanda echo. En aquest cas, podem utilitzar sentències d'"escape" (\n, \t, ...) per a incloure un salt de línia, una tabulació... (Nota: alguns shells de Linux poden tenir la seva pròpia versió de la comanda echo).

#!/bin/bash 
# Introduint salts de línia utilitzant 2 echo
echo "Línia 1: primera línia a visualitzar-se"
echo "Línia 2: segona línia!"

El script anterior es pot simplificar forçant a la comanda echo que interpreti les seqüències d'"escape"

#!/bin/bash 
# Introduint salts de línia utilitzant -e
echo -e "Línia 1: primera línia a visualitzar-se \n Línia 2: segona línia!"

Video - exemple utilització comanda echo

Cometes dobles vs cometes simples

La comanda echo permet l'utilització de cometes simples(') i cometes dobles(") per a visualitzar la informació. Les cometes simples no interpreten el contingut de la informació que contenen: si inclouen una variable mostraran el nom de la variable.
Per contra, les cometes dobles interpreten el contingut que hi ha entre l'obertura i el tancament de les cometes. Si volem escriure un $ utilitzant cometes dobles serà precíes escapar el caràcter de $ amb el símbol "\".

#!/bin/bash 
# File: script1.sh
echo '$PATH - Variable PATH és interpretada com a literal'
echo "\$PATH - Variable PATH és interpretada com a literal"
echo "$PATH - Visualització del contingut de la variable \$PATH"

Video - cometes simples i dobles

Escrivint informació amb Python

Comanda print

Per a visualitzar informació per la pantalla en Pyhon utilitzem la instrucció print. El format de la comanda és:

print([param1][,param2]...)
on paramN pot ser un literal o bé una variable.

Imprimir literals

L'especificació del literal es pot fer utilitzant cometes simples o dobles: en Python és indiferent l'ús d'una o altra opció.

#!/usr/bin/env python3
print("Missatge")
print('Missatge') # Aquestes dues comandes són equivalents

Imprimir variables

Per a imprimir el valor d'una variable, simplement utilitzarem el nom de la variable inclosa entre parèntesis

#!/usr/bin/env python3
edat=34
print(edat)

Imprimir variables i literals de forma conjunta

Si hem de barrejar expressions literals amb valors de variables, l'opció més simple és incloure la informació com a paràmetres en la instrucció print.

#!/usr/bin/env python3
quantitat=100
unitats="Kg"
print("L'estoc actual és de:",quantitat,"(",unitats," )")

Nota: Observeu que tot i que quantitat és de tipus enter, puc incloure aquesta informació sense necessitat de convertir l'expressió al tipus string.
Utilitzant l'operador + (concatenació si algun dels operants és de tipus text) puc reescriure l'expressió anterior:

#!/usr/bin/env python3
quantitat=100
unitats="Kg"
print("L'estoc actual és de: "+str(quantitat)+"( "+unitats+" )")

Nota: l'operador + no pot barrejar variables de tipus numèric i cadenes de caràcters (strings). És per aquest motiu que la inclusió de la funció "str" per a convertir de número a text és obligatòria en aquest cas.

Caràcters especials

Python té definits una sèrie de caràcters especials (\n, \t, ...) que influeixen en la forma en què es visualitza la informació per pantalla (\n per salt de línia, \t per tabulador ...)

#!/usr/bin/env python3
producte1="pomes"
quantitat1=100
unitats="Kg"
producte2="peres"
quantitat2=50
print(producte1,"Estoc:",quantitat1,unitats,"\n"+producte2,"Estoc:",quantitat2,unitats)

Imatge 3
Nota: Utilitzem el símbol + després del salt de línia (\n) per evitar l'espai que s'inclou abans de cada paràmetre.

Imprimir caràcters especials

Tots els caràcters especials comencen amb el símbol de la barra invertida (). Si es vol imprimir aquest símbol amb la comanda print, primer caldrà escapar-la. El caràcter d'escape és la pròpia barra invertida ()

#!/usr/bin/env python3
print("C:\\Windows \nC:\\Program Files \nhem fet \\n per a separar les dues rutes")

Imatge 4
Video - utilitzant la comanda print amb Python versió 3

Bash - Redirecció de la informació

És comú registrar les operacions que realitza un determinat script en un fitxer de log. D'aquesta forma, podem executar el nostre programa en segon pla i comprovar posteriorment quines operacions s'han realitzat, o si hi ha hagut algun error i cal repetir el procés.

Redirecció sortida estàndard

Per a redireccionar la informació que es visualitzaria per pantalla a un fitxer en bash script utilitzarem el símbol > o >> seguit del nom del fitxer.
El símbol > elimina el contingut previ del fitxer i, per tant, aquest només contindrà la informació afegida des del moment de l'última instrucció executada amb l'operador >.
El símbol >> afegeix la informació al contingut del fitxer. Per tant, el fitxer contindrà tota la informació anterior més la nova informació.
Els dos operadors crearan el fitxer en el cas que aquest no existeixi.

#!/bin/bash 
# File: script1.sh
echo "Running script1.sh">/var/log/script1.sh # if /var/log/script1.sh exists, it will be removed.
# First instruction
echo "Instruction 1 executed"
# More instructions ...
# ....
echo "Finished script1.sh">>/var/log/script1.sh # append info to /var/log/script1.sh .

Video - exemple redirecció sortida estandard

Redirecció sortida errors

En un script algunes instruccions poden generar un error per a diversos motius: falta de connexió, error de hardware d'un dispositiu, fitxer inexistent, falta de permisos,...
Per tal de tenir un control dels errors podem redirigir la soritda per defecte (pantalla) dels errors a un determinat fitxer. Per fer-ho , utilitzarem la combinació 2> o 2>> segons si volem eliminar o afegir al contingut del fitxer.

#!/bin/bash 
# File: script1.sh
mkdir /home/user 2>> /var/log/script1.log

El programa anterior s'executarà de forma correcte si el directori /home/user no existeix. En el cas que el directori ja existeixi, s'emmagatzemarà l'error pertinent en el fitxer: /var/log/script1.log
Video - Redirecció sortida estàndard d'errors

Python - Redirecció de la informació

En Python no es poden utilitzar els redireccionaments (>, >>, 2>, ...) tal i com ho fem amb bash. Tot i això, la necessitat de reportar el funcionament del nostre programa continua essent una necessitat en Python.
Una primera opció és utilitzar el redireccionament de bash en l'execució del programa.

python3 programa.py > /var/log/programa.log

Tot i que la instrucció funciona de forma correcte, no hi ha cap forma d'especificar quina informació es vol emmagatzemar i quina no en el fitxer (es guarda tota la informació que es visualitzi).

Redirecció sortida estàndard

Per a poder simular els redireccionaments en bash haurem de treballar directament en fitxers. La idea és associar la sortida estandard a un fitxer, que prèviament haurem d'obrir. Per a treballar amb fitxers amb Python és necessari importar la llibreria sys. Per a obrir un fitxer utilitzarem la instrucció "open". La seva sintaxis és:

fd=open(fitxer,mode)
#!/usr/bin/env python3
import sys  # System-specific parameters and functions
sys.stdout = open('/var/log/script.log','w') # Associació sortida estandard al fitxer
print("Inici execució programa")

El problema que té el codi anterior és mai els missatges s'escriuran per pantalla: la sortida està associada a un fitxer. El següent codi ens permet determinar si volem escriure per pantalla o en un fitxer abans de realitzar la impressió de la informació.

#!/usr/bin/env python3
import sys  # System-specific parameters and functions
# Guardem la referència al fitxer de log
fitxer = open('/var/log/script.log','w')   # w equival a >
# Terminal és la referència a la pantalla (stdout per defecte)
terminal = sys.stdout
sys.stdout = fitxer # associem sortida estàndard al fitxer
print("Inici execució programa")
# Tornem a associar la sortida a la pantalla
sys.stdout = terminal
print("Missatge per pantalla")
fitxer.close() # tanquem el fitxer

Redirecció sortida error

De forma semblant a la redirecció de la sortida estàndard podem redireccionar la sortida d'errors: sortida associada a la visualització dels errors en l'execució del programa.
En aquest cas, enlloc d'utilitzar stdout utilitzarem stderr per a referenciar la sortida d'errors.
En aquest cas el que farem és crear una carpeta.

#!/usr/bin/env  python3
import sys  # System-specific parameters and functions
import os   # Miscellaneous operating system interfaces
err = open("/var/log/script.err","w")
sys.stderr = err
os.makedirs("/home/user") # si el directori ja existeix, aquesta instrucció donarà un error
err.close()

Redireccionament per afegir

Els redireccionaments que hem vist fins aquest moment sempre eliminen el contingut del fitxer. Això vol dir que cada vegada que s'executa el programa el fitxer de "log" s'elimina i es torna a crear. A vegades ens interessa tenir informació de totes les execucions d'un determinat script: per tant, hem d'afegir la informació al fitxer.
En aquest cas hem d'obrir el fitxer amb mode "append" (a). Substituirem el mode d'obertura de "w" a "a".

#!/usr/bin/env python3
import sys  # System-specific parameters and functions
import os   # Miscellaneous operating system interfaces
err = open("/var/log/script.err","a")  # a per append
sys.stderr = err
os.makedirs("/home/user") # si el directori ja existeix, aquesta instrucció donarà un error
err.close()

Video - Redirecció de la sortida estàndard amb Python

Bash - Línia d'arguments de comanda

Moltes comandes en Linux tenen la possibilitat de rebre informació especificada durant l'execució de la comanda. Aquesta informació permet particularitzar el funcionament de la comanda. Així, per exemple, la comanda 'ls /home' o 'ls -alis /home' visualitzen els fitxers del directori home, tot i que la informació que es visualitza en un cas o en un altre és diferent: la diferència en aquest cas ve determinada per l'argument -alis.
Moltes vegades ens interessa tenir una funcionalitat semblant en els nostres scripts: l'usuari decideix en temps d'execució quines opcions vol activar/desactivar del nostre programa.

Recollir els arguments

El sistema operatiu Linux utilitza unes variables especials $1,$2,...,$n on emmagatzema la informació que s'envia en una línia de comandes. Així, per exemple, suposem que tenim un programa de nom script.sh.

#!/bin/bash
echo "Primer argument de la linia de comandes: $1"
echo "Segon argument de la linia de comandes: $2"

Un cop hem associat els permisos d'execució podem executar el programa amb:

./script.sh argument1 argument2

Imatge 10
En el cas que un argument contingui espais, hem d'utilitzar les cometes simples (') o dobles (") quan executem el programa.

./script.sh "argument 1" "argument 2"

Imatge 11
Nota: el màxim d'arguments que podem passar són 9 ($1..$9).

Contabilitzant els arguments

Una de les operacions importants que cal realitzar quan un programa permet passar arguments és poder determinar quants arguments l'usuari està especificant. Si el nombre d'arguments no és el correcte, el nostre programa ha de finalitzar amb un missatge d'error. Per a obtenir el número d'arguments d'un script disposem de la variable especial $#

#!/bin/bash
echo "Total arguments: $#"

El script anterior ens mostra el total d'arguments amb els quals s'ha executat el nostre script.
Video - Arguments de línia de comanda

Altres variables especials

Apart de les ja mencionades $1,..,$9 i $# el sistema Linux incorpora altres variables amb diferents finalitats

Finalització correcte/errònia comanda

La variable $? ens indica si l'execució de l'última comanda s'ha efectuat de forma correcte o no. La comanda ens retorna un 0 si no s'ha produït cap error i un número diferent de 0 si hi ha succeït algun error en l'execució de la comanda anterior

#!/bin/bash
mkdir /home/user # suposem que el directori no existeix
echo "Error: $?" # Imprimeix Error: 0 
mkdir /home/user 2>/dev/null # No volem visualitzar error per pantalla!
echo "Error: $?" # Imprimeix Error: 1 (0<>1 => Error)
echo "Error: $?" # Imprimeix Error:0 (sense error en l'execució de la comanda anterior)

Usuari execució

Amb la variabla $USER podem determinar quin usuari està executant el programa. Per exemple, podem utilitzar aquesta variable per a guardar en un registre quins usaris han executat un determinat programa i quan ho han fet.

Temps execució

Amb la variable $SECONDS ens informa el nombre de segons transcorreguts des de l'inici de l'execució del programa.

Python - Línia d'arguments de comanda

De la mateixa forma que en un programa bash podem enviar informació d'entrada quan l'executem precisem d'aquesta funcionalitat en els nostres programes de Python. Per a desenvolupar aquest funcionament és precís importar la llibreria de sistema (sys).

Recollir els arguments

Python emmagatzema tots els arguments que s'envien en la crida d'un programa a la variable "argv". Aquesta variable és un vector (o array) on cada posició s'hi emmagatzema un determinat valor. La variable està disponible en la llibreria sys i , per tant, el primer que haurem de fer és importar aquesta llibreria.

#!/usr/bin/env python3
import sys
print("Primer argument: ",sys.argv[1])
print("Segon argument: ",sys.argv[2])

Nota: En aquest cas és important que en la nostra crida com a mínim hi hagi 2 arguments, ja que en cas contrari , la referència a "sys.argv[2]" donarà un error.

Video - Utilització de paràmetres d'entrada en Python

Exercicis - bash

  1. Crea un script de nom hello.sh que visualitzi 'Hello World' per pantalla.
  2. Executa l'script del punt 1 cridant el programa només hello.sh.
  3. Crea un script de nom 'run.sh' que guardi en un fitxer de log "Execució script run.sh".
  4. Modifica el script anterior de forma que mostri per pantalla "Estat de l'execució: N", on N serà un 0 si el script s'ha executat de forma correcte o un número diferent de zero en cas contrari.
  5. Executa el script anterior obtenint: "Estat execució: 0".
  6. Executa el script del punt 4 però en aquest cas, enlloc de mostrar un 0 ha de mostrar un valor diferent de 0.
  7. Crea un script que mostri per pantalla el nombre d'arguments que s'han introduït
  8. Crea un script que permeti la recepció de 4 arguments. Visualitza per pantalla els arguments número 1,3 i 4. Cal mostrar cada argument en una línia separada.
  9. Modifica el script del punt anterior de forma que només apareixi una vegada la comanda echo. La visualització ha de ser la mateixa.
  10. Modifica el script del punt 3, de forma que enlloc de visualitzar "Execució script run.sh" substitueixi run.sh pel nom del script que s'està executant. Això vol dir que si es canvia el nom del script run.sh per execucio.sh , el programa mostrarà "Execució script execucio.sh"

Exercicis - Python

Traspassa tots els exercicis de bash a Python excepte els exercicis 4, 5 i 6.

EXPORT

L'execució normal d'un script es fa en un subshell creat a partir del shell actiu de l'usuari. Per tant, per defecte, els canvis que es fan a les variables del shell actual no es transmeten per defecte al subshell.

Recuperació variables del shell (bash)

Si volem que una variable estigui accessible des del subshell, podem utilitzar dues tècniques diferents:

  1. Executar el script utilitzant el shell actual. L'espai en que s'executen els dos programes és el mateix i, per tant, les variables són compartides. Els canvis de valor a les variables dins el script són permanents.
. ./nomscript.sh    # Utilitzem un . abans de la ruta absoluta/relativa del script
  1. Exportar la variable des del shell actual.

    export nomvariable  # sense el símbol del $
    

    Nota:Excepte que s'executi el programa en el mateix shell (opció 1) els canvis només es propaguen des del shell cap al subshell; els canvis realitzats a les variables en el subshell no són visibles en el shell. Video - explaining export

    Recuperació variables del shell (Python)

    Per a recuperar una variable d'entorn (o del shell) en Python cal importar en primer lloc la llibreria del sistema (os). Aquesta llibreria defineix una variable (array) de nom environ que conté totes les variables d'entorn. Utilitzem el nom de la variable com a índex de l'array.

export MYVAR="Nova variable" # Definint i exportant variable MYVAR

En el següent programa amb Python recuperem el valor de la variable exportada MYVAR i de la variable de sistema MYVAR

#!/usr/bin/env python3
import os
print("Variable entorn del sistema: ",os.environ["PATH"])
print("Variable creada ",os.environ["MYVAR"])

NOTA: per a canviar el valor d'una variable d'entorn podem assignar directament el valor desitjat a la variable. Tot i això, el nou valor només estarà disponible dins del shell on s'està executant el programa.

#!/usr/bin/env python3
import os
print("Variable entorn del sistema: ",os.environ["PATH"])
print("Variable creada ",os.environ["MYVAR"])
os.environ["MYVAR"]="Nou valor"
print("Valor MYVAR:",os.environ["MYVAR"])

Video - Variables d'entorn en Linux i Python

Demanant informació a l'usuari

Anteriorment hem vist que a un programa se li pot enviar informació a través de paràmetres. Aquesta és una bona tècnica a utilitzar quan un script volem que faci una determinada feina sense necessitat d'interacció amb l'usuari. De totes formes, l'utilització de variables és poc intuïtiva quan el programa ha de ser executat per un usuari "no tècnic". En aquests casos podem utilitzar la instrucció "read", que ens permet mostrar un missatge a l'usuari i guardar la informació introduïda per l'usuari en una variable per a la seva utilització posterior. Un exemple de les dues tècniques (paràmetres i read) el tenim en Linux amb les instruccions useradd i adduser.

Instrucció read (bash)

El format més bàsic de la instrucció read és:

#!/bin/bash
read nom_variable
echo $nom_variable

Aquesta instrucció espera a que l'usuari introdueixi una informació (no sabem quina!) pel teclat. Quan l'usuari polsi la tecla de retorn la instrucció read es donarà per finalitzada i el text introduït per l'usuari s'emmagatzemarà en la variable nomVariable.
Una millor alternativa consisteix en incloure el missatge informatiu a visualitzar a l'usuari. Per fer-ho , utilitzarem l'opció -p de la comanda read.

#!/bin/bash
read -p "Nom usuari: " nomVariable
echo $nomVariable

Video - Comanda read en bash script

Instrucció input (Python)

Per a demanar dades a l'usuari amb Python utilitzem la comanda input. El format de la comanda és

_variable_ = input(_Text a visualitzar_)

On Text a visualitzar és el missatge que es vol mostrar a l'usuari i variable és el nom de la variable on s'emmagatzemarà la informació introduïda per l'usuari.
Video - Obtenir informació de l'usuari

Obtenir informació d'un fitxer (bash)

La comanda "read" es pot utilitzar també per a obtenir la informació d'un fitxer. En aquest cas podem utilitzar un redireccionament, però enlloc de ser un redireccionament de sortida serà un redireccionament de l'entrada. Utilitzarem el símbol '<'.
En relació al codi a utilitzar no serà precís realitzar cap canvi en el nostre script, però sí que haurem d'indicar en l'execució del programa de quin fitxer ha de llegir les dades.

#!/bin/bash
# file name: script.sh
read first_line
echo $first_line

Fitxer data.txt

primera línia de text

Crida del programa

bash script.sh < data.txt

Video - redirecció de l'entrada estàndard

Obtenir informació d'un fitxer (python)

El redireccionament de l'entrada estàndard en bash funciona de manera similar en Python. Cada una de les línies introduïdes en el fitxer que conté la informació és llegida per una instrucció input de Python.
Video - redirecció de l'entrada estàndard

#!/usr/bin/env python3
# file name: script.py
first_line = input("Get first line")
print("First line: ",first_line)

Fitxer data.txt

primera línia de text

Crida del programa

python3 script.py < data.txt

Piping

"Piping" és el procés on la informació de sortida de l'execució d'un programa passa a formar part de l'entrada d'un altre programa. Per exemple:

cat fitxer | wc

La comanda cat fitxer visualitza el contingut de "fitxer" per pantalla. La pipe indica que la informació s'ha d'enviar a un altre procés (enlloc de la pantall): wc . 'wc' processa la informació rebuda contabilitzant el número de línies, paraules i caràcters.

Utilitzant piping amb bash script

#!/bin/bash
# file name: script.sh
read first_line
echo $first_line

Fitxer data.txt

primera línia de text

Crida del programa amb redireccionament utilitzant piping

cat data.txt | bash script.sh 
# equival a
bash script.sh < data.txt

Utilitzant piping amb python

#!/usr/bin/env
# file name: script.py
first_line=input("Text")
print(first_line)

Fitxer data.txt

primera línia de text

Crida del programa amb redireccionament utilitzant piping

cat data.txt | python3 script.py
# equival a
bash script.py < data.txt

Exercicis - bash

  1. Crea un script que demani dues informacions. Cal visualitzar les dues informacions per pantalla. Per exemple, si l'usuari introdueix primer "Hola" i després "Adeu", cal mostrar per pantalla "Hola i Adeu".
  2. Modifica el script anterior per tal que en el text es visualitzi també informació passada per la línia de comanda. Per exemple,

    bash script Que tal
    

    i l'usuari introdueix primer "Hola" i després "Adeu", cal mostrar per pantalla "Hola Que tal i Adeu" . En la crida com a màxim es passaran 2 paràmetres.

  3. Modifica el script anterior afegint variables d'entorn: 2 que ja existeixin en el sistema i 2 de noves.
  4. Crea un script que llegeixi les tres primeres línies d'un fitxer. Cal imprimir la 1a i la 3a línia. Fes-ho utilitzant els diferents operadors de redireccionament d'entrada.
  5. Crea un script que visualitzi només algunes de les columnes de la comanda "ls -alis" . Per exemple, que es visualitzin 2 columnes en cada una de les línies.

    Exercicis - python

    Traspassa els exercicis de bash a Python

    Operadors matemàtics en bash

    Alguns programes requereixen de la realització de càlculs. Per exemple, quin és l'espai ocupat en disc pels tres fitxers més grans d'un directori, quants fitxers hi ha en un directori... 'bash' incorpora els següents operadors matemàtics:

Operador Operació
+, -, /*, / sumar, restar, multiplicar, dividir
var++ Increment amb una unitat
var-- Decrement amb una unitat
% Reste de la divisió

Utilització operadors matemàtics

Per a poder utilitzar aquests operadors ho podem fer de diverses formes: let, expr, ... En aquest document s'explicarà només l'ús del doble parèntesis "$(( ))" on l'expressió matemàtica s'inclou entre els parèntesis.
Nota: Amb bash només es permeten les operacions amb valors enters. Així, per exemple, si dividim 5/2 el resultat serà 22. Per a poder realitzar valors amb números reals hem d'utilitzar una eina com bc(https://www.lifewire.com/use-the-bc-calculator-in-scripts-2200588)

#!/bin/bash
#file name: script.sh
valor1=10
valor2=20
result=$(( $valor1 + $valor2 ))
result2=$(( $valor1 % 2 ))
echo "$result $result2"

La utilització del $ dins del parèntesis és opcional. Es pot "simplificar" la notació utilitzant:

#!/bin/bash
# file name: script.sh
valor1=10
valor2=20
result=$(( valor1 + valor2 )) # equival a result=$(( $valor1 + $valor2 ))
result2=$(( valor1 % 2 ))
echo "$result $result2"

Els dos exemples anteriors són equivalents, tot i que el segon exemple té una sintaxis més simple.

Operadors autoincrement i autodecrement

Els operadors ++ i - - incrementen o decrementen el valor de la variable en una unitat. La seva utilització és semblant a la resta d'operadors matemàtics, però en aquest cas només hi ha una variable involucrada.

#!/bin/bash
# file name: script.sh
valor1=10
echo "$valor1"
(( valor1++ )) #incrementa la variable valor1 amb 1 unitat
echo "$valor1"

Conversió variables amb bash

Totes les expresssions incloses entre els doble parèntesis han de ser convertibles a valors enters. En cas contrari el programa ens donarà un error. La conversió es fa de forma automàtica.
Video - Conversions i operacions matemàtiques en bash

Operadors matemàtics en Python

Els operadors matemàtics disponibles en Python són:
Operador Operació
+, -, /*, / sumar, restar, multiplicar, dividir
% Reste de la divisió
Cal tenir en compte que aquests operadors s'han d'utilitzar amb variables que emmagatzemin valors numèrics o bé que es puguin convertir a numèric.
A diferència de bash script no es disposa d'un operador ++ o -- per incrementar o decrementar les variables en una unitat.

#!/usr/bin/env   python3
# file name: script.py
num1=10
num2=20
result=num1+num2
print(result)

Conversió variables amb Python

A diferència de bahs Python implementa diferents tipus o classes de variables conforme al valor assignat. Cal tenir en compte que tots els valors introduïts per l'usuari són tractes com a string. Video - Càlcul de dades d'usuari amb comanda input

bash - Longitud d'una cadena

Una de les operacions habituals en un script és determinar la longitud d'un argument passat a un script, o bé d'una informació introduïda per l'usuari. A diferència d'altres llenguatges de programació, no hi ha cap funció length o strlen. Per a obtenir la longitud d'un string hem d'utilitzar la forma:

variable=${\#variable2}

Un exemple d'utilització seria:

#!/bin/bash
# file name: script.sh
valor="Hola"
longitud=${#valor}
echo "$longitud"

Python - Longitud d'una cadena

Per a obtenir la longitud d'un string, un array... amb Python disposem de la funció len.

#!/usr/bin/env python3
# file name: script.py
text = input("Entra algun text")
print("Longitud de ",text,":",len(text))

results matching ""

    No results matching ""