1.15. Disseny de protocols automàtics al terminal
En aquest apartat us introduireu en el disseny de protocols automàtics en un terminal bash. Dins del camp de la bioinformàtica aprendre a dissenyar protocols és útil per diverses raons. En primer lloc, permet l’automatització de tasques repetitives, la qual cosa estalvia temps i redueix el risc d’errors. En segon lloc, permet la creació de fluxos de treball reproduïbles, que són essencials per a la recerca científica. En tercer lloc, bash és una eina poderosa i flexible que es pot utilitzar per manipular conjunts de dades grans i realitzar anàlisis complexes. Finalment, l’ús de protocols (en anglès, script) bash facilita la col·laboració i l’intercanvi de protocols, cosa que fa que sigui més fàcil per als investigadors reproduir la feina d’altres i construir-hi. En general, el disseny de protocols automàtics en un terminal bash és una forma eficient i efectiva de realitzar anàlisis de bioinformàtica.
En dissenyar un protocol en un terminal bash, hi ha diversos aspectes tècnics i paràmetres que s’han de tenir en compte. Aquí es presenten els aspectes més importants que cal considerar.
- Sintaxi i gramàtica: el protocol ha de tenir una sintaxi i una gramàtica ben definides que siguin fàcils d’entendre i seguir.
- Maneig d’errors: el protocol ha d’estar dissenyat per manejar errors i excepcions de manera elegant. Això inclou la definició de codis d’error i missatges.
- Seguretat: el protocol ha d’estar dissenyat per garantir la privacitat i seguretat de les dades. Això inclou mesures com l’encriptació, l’autenticació i el control d’accés.
- Compatibilitat: el protocol ha de ser compatible amb el hardware i el software del sistema en el qual s’utilitzarà.
- Eficiència: el protocol ha d’estar dissenyat per ser eficient i optimitzar l’ús dels recursos del sistema, com la CPU i la memòria.
- Escalabilitat: el protocol ha d’estar dissenyat per ser escalable, de manera que pugui manejar quantitats creixents de dades i usuaris sense degradació del rendiment.
- Documentació: el protocol ha d’estar ben documentat, amb instruccions clares i exemples per a la seva implementació i ús.
- Proves: el protocol ha de ser provat exhaustivament per assegurar que la seva funcionalitat i rendiment compleixin amb els requisits.
Tenint en compte aquests aspectes tècnics i paràmetres, el protocol pot ser dissenyat per ser efectiu, segur i eficient en el seu funcionament. En aquest apartat se us mostra com dissenyar protocols senzills, i no es tindrà en compte tot el que s’ha esmentat anteriorment, però sempre s’ha de treballar tenint en compte totes les consideracions esmentades.
En aquest exercici se us mostrarà com generar un protocol per obtenir informació biològica rellevant a partir de 3 seqüències FASTA. T’animo a realitzar tots els passos que es mostren a continuació. Obre un terminal i comença.
1) Crea un directori:
$ mkdir fasta_sequence
$ cd fasta_sequence
2) Descarrega, en l’anterior directori i des de la base de dades ENA (European Nucleotide Archive), les seqüències FASTA associades als gens humans de BRCA1, BRCA2 i HOXB13:
- Uniprot ID: P38398, ENA accesion number: AC060780
https://www.ebi.ac.uk/ena/browser/view/AC060780 - Uniprot ID: P51587, ENA accesion number: AL137247
https://www.ebi.ac.uk/ena/browser/view/AL137247 - Uniprot ID: Q92826, ENA accesion number: BC007092
https://www.ebi.ac.uk/ena/browser/view/BC007092
3) Quan es volen executar una sèrie d’ordres de forma seqüencial al terminal bash, es crea un script o protocol i es guarda en un arxiu de text amb extensió «.sh
». Aquest script ens permet referir-nos internament als seus paràmetres de manera genèrica, la qual cosa significa que pot funcionar en qualsevol grup d’arguments del mateix tipus. A més, per fer-lo més flexible s’han d’especificar aquests paràmetres genèrics dins de l’script, de manera que, quan s’invoqui l’script des de la línia d’ordres, podem substituir aquests paràmetres genèrics per valors específics proporcionats per l’usuari juntament amb el nom de l’ordre. En utilitzar aquest enfocament, es poden automatitzar tasques repetitives o processos complexos, la qual cosa fa que la feina sigui més eficient i consistent.
$ vi analitza_fasta.sh
4) Abans d’introduir el codi per generar un protocol, dues consideracions a tenir en compte:
- En la primera línia del protocol s’ha d’indicar, sempre, l’intèrpret d’ordres
bash
(GNU Bourne-Again SHell). En la majoria dels sistemes coexisteixen altres intèrprets comsh
(Bourne) ocsh
(C shell). El directori on es localitza l’intèrpret s’escriu a continuació del conjunt de símbols#!
- Per introduir comentaris en el protocol s’ha d’introduir el símbol
#
(en anglès, shebang) a la primera columna del fitxer.
5) Escriu cadascuna de les següents línies en el fitxer sh que acabes d’obrir. Has d’escriure en mode insert, el primer que has de fer és teclejar la lletra i
, i a continuació escriu les línies següents:
#!/bin/bash
# Aquest protocol analitza un fitxer que conté una única seqüència FASTA
# Primer, se subministra el nom del fitxer com a argument
if [ $# -eq 0 ] then echo "Per favor, subministra un nom de fitxer com a argument" exit 1 fi
# El símbol $$ indica el PID del procés
echo "El valor del PID del procés és"; echo "PID és $$";
# $1 representa el primer argument a analitzar. En aquest cas el nom del fitxer FASTA
echo "La mida del fitxer FASTA és:"; ls -sh $1 | gawk '{print $1}'; echo "Nombre de línies del fitxer FASTA:"; wc -l $1 | gawk '{ print $1 }'; echo "Extreu les primeres set línies del fitxer"; head -7 $1;
# Les següents dues línies considera comentar-les, si la seqüència FASTA té moltes línies
echo "Extreu la seqüència del fitxer FASTA"; sequence=$(awk '/^>/ {next} {printf "%s", $0} END {print ""}' "$1") echo "$sequence"
# Càlcul de la longitud de la seqüència
length=$(echo -n "$sequence" | wc -c) echo " Longitud de la seqüència: $length nucleotids"
# Compte el número de nucleòtids que té la seqüència
num_A=$(grep -o 'A' <<< "$sequence" | wc -l) num_C=$(grep -o 'C' <<< "$sequence" | wc -l) num_G=$(grep -o 'G' <<< "$sequence" | wc -l) num_T=$(grep -o 'T' <<< "$sequence" | wc -l)
# S’han generat in situ 4 noves variables. Imprimeix cada nombre de nucleòtids
echo "Nombre de nucleòtid A: $num_A" echo "Nombre de nucleòtid C: $num_C" echo "Nombre de nucleòtid G: $num_G" echo "Nombre de nucleòtid T: $num_T"
# Càlcul del contingut GC de la seqüència
num_GC=$((num_C + num_G)) total=$((num_A + num_C + num_G + num_T)) gc_content=$(bc -l <<< "scale=2; $num_GC / $total * 100") echo "GC contenido: $gc_content%"
# Identificació dels ORFs de la seqüència
echo "Identificant ORFs..." ORFs=$(echo -n "$sequence" | tr 'ATCG' 'tacg' | grep -Eo '(atg([acgt]{3})*?(taa|tag|tga))+' | tr 'tacg' 'ATCG') if [ -z "$ORFs" ] then echo "No es troben ORFs" else num_ORFs=$(echo -n "$ORFs" | awk '{print length}' | wc -l) echo "Nombre d'ORFs: $num_ORFs" echo "ORFs: $ORFs" fi
Salva el fitxer que s’ha creat escrivint: wq! analitza_fasta.sh
6) Per executar l’script, salva l’anterior fitxer amb l’extensió “.sh
” i fes-lo executable amb l’ordre chmod +x
. Executa’l amb el nom del fitxer FASTA a analitzar:
$ pwd
/home/student/fasta_sequence
$ chmod +x analitza_fasta.sh
$ ./analitza_fasta.sh AC060780.18.fasta
7)Fins ara s’ha generat un protocol per analitzar fitxers FASTA, s’ha executat i comprovat que funciona. El següent pas és executar l’anterior fitxer d’anàlisi en un directori amb diferents seqüències. Per a això, es genera un altre protocol que inclogui l’anterior. El nou protocol es diu analitza_fasta_dir.sh
. Els passos per seguir són:
$ pwd
/home/student
$ vi analitza_fasta_dir.sh
Les ordres que cal introduir en aquest fitxer són:
#! /bin/bash echo "S’inicia l’execució amb el PID $$"; echo "Nombre d’arguments a analitzar $#"; echo "El nom del directori a analitzar $1"; echo "Els noms dels fitxers que s’analitzen són"; ls $1; echo "Execució del protocol d’anàlisi FASTA per a cadascun dels fitxers en el directori"; ls $1 | while read file; do echo "execució analitza_fasta.sh $file"; ./analitza_fasta.sh $1/$file; done
Salva el fitxer que s’ha creat escrivint :wq! analitza_fasta_dir.sh
8) Per executar l’script, salva l’anterior fitxer amb l’extensió .sh
i fes-lo executable amb l’ordre chmod +x
. Executa-ho amb el nom del directori que conté els fitxers FASTA a analitzar:
$ pwd
/home/student
$ cp fasta_sequence/analitza_fasta.sh .
$ chmod +x analitza_fasta_dir.sh
$ ./analitza_fasta_dir.sh fasta_sequence
Es pot observar que els protocols que s’executen es troben en el directori actual de treball (./) en lloc de només invocar el seu nom. No obstant això, un cop s’està segur que l’script funciona correctament, és més convenient guardar tota la nostra col·lecció de protocols en un sol directori del sistema. D’aquesta manera, no s’han de mantenir múltiples còpies i es podran executar des de qualsevol lloc en el nostre arbre de directoris.
Les plataformes Gnu/Linux tenen un conjunt de variables globals que contenen dades de caràcter general. Es resumeixen a la taula següent, la taula 16.
Taula 16. Ordres per a l’execució de scripts.
Ordre | Descripció |
set |
Estableix valors que seran usats pels programes, aplicació, scripts |
echo |
Imprimeix el que se li encarrega que faci |
printenv |
Llista la llista completa de variables d’entorn de la teva versió Gnu/Linux |
which |
Localitza els arxius executables d’una determinada aplicació |
export |
Crea/modifica una variable del sistema |
L’ordre set
a Gnu/Linux mostra i estableix variables d’entorn per a la sessió actual. S’utilitza per veure el valor de les variables d’entorn del sistema i també per assignar valors a noves variables d’entorn. L’ordre echo
, d’altra banda, s’utilitza per mostrar missatges de text o el valor de les variables a la pantalla. També es pot utilitzar per escriure text en arxius o per concatenar diversos missatges de text.
L’avantatge d’utilitzar echo és que permet seleccionar i mostrar només la informació que es necessita, el que fa que sigui més fàcil de llegir i entendre. D’altra banda, l’avantatge d’utilitzar set és que permet establir i modificar variables d’entorn, la qual cosa pot ser útil en automatitzar tasques i scripts a Gnu/Linux.
Obre un terminal de Gnu/Linux. Pots veure la llista completa de variables d’entorn de la teva versió de Gnu/Linux utilitzant l’ordre printenv
. Pots tenir una llista més manejable afegint-hi diferents ordres:
$printenv | less
Cada línia conté el nom de la variable d’entorn Gnu/Linux seguit de = i del valor. Per exemple:
HOME=/home/student
Això vol dir que HOME és una variable d’entorn de Gnu/Linux que té el valor establert com a directori /home/student.
Les variables d’entorn solen estar en majúscules, tot i que també pots crear variables d’entorn en minúscules. La sortida de printenv
mostra totes les variables d’entorn en majúscules. Una cosa important per tenir en compte és que les variables d’entorn de Gnu/Linux distingeixen entre majúscules i minúscules. Si desitges veure el valor d’una variable d’entorn específica, pots fer-ho considerant el nom d’aquesta variable com a argument de l’ordre printenv
. La cadena de caràcters completa es veuria així en la línia d’ordre:
$ printenv HOME
/home/student
$ echo $USER
student
La sintaxi bàsica per crear una variable d’entorn a Gnu/Linux és la següent. És fàcil aconseguir-ho, només es necessita especificar un nom i un valor. Seguirem la convenció de mantenir totes les lletres en majúscules per al nom de la variable, i l’establirem com una cadena simple.
$ HIB_VAR='BioInformatica i BioEstadistica!'
$ export HIB_VAR
$ export HIB_VAR='BioInformatica i BioEstadistica!' #en una única línia
S’han fet servir cometes simples, ja que el valor de la variable conté un espai. A més, s’han utilitzat cometes simples perquè el signe d’exclamació és un caràcter especial en la shell bash que normalment s’expandeix a l’historial de bash si no s’escapa o es col·loca entre cometes simples. Ara tenim una variable de la shell. Aquesta variable està disponible en la nostra sessió actual, però no es transmet als processos secundaris.
Es pot comprovar, buscant la nostra nova variable dins de la sortida de set:
$ set | grep HIB_VAR
HIB_VAR='BioInformartica i BioEstadistica!'
Si la variable s’ha definit correctament, podràs utilitzar-la en qualsevol protocol que executis en la mateixa sessió del terminal. Per exemple, si crees un arxiu de script en bash que requereix utilitzar la variable HIB_VAR
, simplement pots referir-t’hi utilitzant el símbol $
. Per exemple, si el teu arxiu de script s’anomena myscript.sh
i conté el següent codi:
#! /bin/bash echo " El valor de HIB_VAR es: $HIB_VAR"
Si s’executa l’arxiu de script en la mateixa sessió del terminal utilitzant l’ordre bash,
$ chmod +x myscript.sh
$ bash myscript.sh
BioInformatica i Bioestadistica!
l’arxiu de script hauria d’imprimir el valor de la variable HIB_VAR
que vas definir prèviament. Per revertir el valor d’una variable es pot fer servir l’ordre unset
.
$ echo $HIB_VAR
BioInformartica i BioEstadistica!
$ unset HIB_VAR
$ echo $HIB_VAR
D’altra banda, tens en compte que, si tanques la sessió del terminal i la tornes a obrir, hauràs de tornar a definir la variable local utilitzant l’ordre export
. Per evitar això, pots agregar la definició de la variable HIB_VAR al teu arxiu d’inici de bash (per exemple, ~/.bashrc
), de manera que la variable estigui disponible cada vegada que iniciïs una nova sessió del terminal.
L’ordre which
és una eina que permet trobar ràpidament els arxius executables d’una determinada aplicació i localitza els fitxers executables mitjançant la variable d’entorn PATH.
$ which nano docker gawk
/usr/bin/nano /usr/bin/docker /usr/bin/gawk
Finalment, es defineix la variable PATH. El contingut de la variable PATH és una cadena que conté paths
de directoris separats per dos punts, i aquests són els directoris en què la shell busca l’ordre que l’usuari escriu des del teclat.
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin: /usr/games:/usr/local/games:/snap/bin
La recerca no es realitza en l’ordre en el qual estan els directoris en la variable PATH. Quan s’escriu una ordre a la shell buscarà primer a /usr/local/bin
, després a /usr/bin
, a continuació a /usr/games
i finalment a /snap/bin
. Des del moment en què la shell troba l’ordre, deté la recerca i executa l’ordre trobada. Podem escriure una ordre utilitzant:
- El seu nom:
El path absolut (/bin/cat /etc/passwd ).
El path relatiu (utilitzant «.» o «….» en general per als programes o scripts que no es troben al PATH).
Es pot afegir un directori a la variable PATH, afegim el directori on es troben tots els scripts que es generin. - Únicament per a la sessió activa:
Si desitges afegir, per exemple:/home/student/HIB_scripts
a la variablePATH
, escriu a la shell el següent segons el cas.
# Per tenir el directori al final del PATH:
$ export PATH=$PATH:/home/student/HIB_scripts
# Per tenir el directori a l’inici del PATH:
$ export PATH=/home/student/HIB_scripts/:$PATH
Ara pots utilitzar el programa escrivint simplement el seu nom. En desconnectar-se, PATH reprendrà al seu valor per defecte, llavors /home/student/HIB_scripts no existirà més.
- De manera permanent:
Si desitges configurar PATH de forma permanent has d’editar l’arxiu de configuració de la seva shell de connexió. Com que en general la shell bash és el més utilitzat, has d’editar l’arxiu: /home/user/.bashrc. L’ordre llavors seria:$ echo 'export PATH=$PATH:/home/student/HIB_scripts' >> /home/user/.bashrc
Després d’això, en cada connexió la variable PATH contindrà el directori /home/student HIB_scripts. Aquesta operació pot ser executada per l’usuari student, no es necessiten els permisos de root.