Sessió 3 dia 04/04

Entrada i sortida estàndard
Redirecció d'entrada i sortida
Redirecció de sortida no destructiva
Pipes (canonades)
Grep
Exercicis
Resum d'ordres del terminal. Operacions amb arxius

Entrada i sortida estàndard

Normalment les ordres usen el que és conegut com entrada i sortida estàndard (stdin i stdout respectivament, ho pots trobar en /dev/stdin i /dev/stdout) que no són ni més ni menys que el teclat i la pantalla.

Per veure això usarem la següent ordre:

cat [opcions] [llistadefitxers]

'Cat' en si és un concatenador de fitxers que imprimeix la sortida per la sortida estàndard, les opcions no les veurem ja que no són molt interessants. Ens servirà per visualitzar els fitxers i si escrivim 'cat' sense paràmetres llegirà de l'entrada estàndard i escriurà en la sortida estàndard.

Redirecció d'entrada i sortida

L'intèrpret d'ordres ens permet redireccionar la sortida estàndard a un fitxer usant el símbol '>'. Per veure com funciona què millor que un exemple:

ramon@portatil:/directori$ ls
dir1 dir2
ramon@portatil:/directori$ ls >~/kk
ramon@portatil:/directori$ cat ~/kk
dir1
dir2
ramon@portatil:/directori$

La redirecció d'entrada és similar, només que s'usa el caràcter '<' Vegem un exemple:

ramon@portatil:/directori$ cat ~/kk
dir1
dir2
ramon@portatil:/directori$ cat < ~/kk
dir1
dir2
ramon@portatil:~/directori$

En aquest exemple veiem que el resultat és el mateix, òbviament.

Haig de destacar que la redirecció de sortida és una redirecció destructiva, amb això vull dir que si no existeix l'arxiu el crea i si existeix el sobreescriu, i això potser no ho desitgem.

Redirecció de sortida no destructiva

Imaginem que volem fer una llista de la compra, llavors escriuríem alguna cosa així:

ramon@portatil:/directori$ cat > llistadelacompra
xampu
gominoles
cervesa
jb
(Aquí vaig prémer Ctrl+D)
ramon@portatil:/directori$

I se'ns obliden les aspirines:

ramon@portatil:/directori$ cat > llistadelacompra
aspirines
ramon@portatil:/directori$ cat llistadelacompra
aspirines
ramon@portatil:/directori$

Doncs ara ho acabem d'espatllar, ja que la llista la hi vam donar a Manolito i només ens va portar aspirines. Per evitar alguna cosa tan absurda i surrealista com això tenim la redirecció de sortida no destructiva, per a això usem '>>', vegem l'exemple:

ramon@portatil:/directori$ cat > llistadelacompra
xampu
gominoles
cervesa
jb
ramon@portatil:/directori$ cat >> llistadelacompra
aspirines
ramon@portatil:/directori$ cat llistadelacompra
xampu
gominoles
cervesa
jb
aspirines
ramon@portatil:/directori$

Amb això ja ens estalviem el problema. Suposo que ja haureu deduït avantatges de la redirecció a part de fer la llista de la compra, no? (tan simples com guardar el llistat de 'ls' en un fitxer i tan complicat com estalviar-nos teclejar les ordres que ens demanen moltes dades).

Pipes (canonades)

Per al següent exemple veurem altra ordre que el que fa és ordenar el que li entra i retornar-lo ordenat.

sort [opcions] [llistadefitxers]

No veurem les opcions de moment (sempre pots fer 'man sort' si t'interessa). Vegem abans de totes maneres com es comporta sort sense opcions:

ramon@portatil:/directori$ sort llistadelacompra
aspirines
cervesa
gominoles
jb
xampu
ramon@portatil:/directori$

Observem que ens retorna tot ordenat.

Seria molt interessant poder unir la sortida d'un programa amb l'entrada d'un altre i construir una cadena d'ordres. Imagineu-vos que en el cas anterior si a Manolito no li ordenem la llista es perd (no es molestin els Manolos, però algun nom hauria de tenir la víctima), el millor seria fer la llista amb 'cat', unir la sortida amb 'sort' i redireccionar al fitxer on volem guardar-lo, i per a això usem el caràcter '|' (la del AltGr +1). El que fem amb aquest símbol és crear una pipe, que és com he explicat unir la sortida d'una ordre amb l'entrada d'una altra. Millor un exemple:

ramon@portatil:/directori$ cat < llista_de_la_compra | sort > novallista
ramon@portatil:/directori$ cat novallista
aspirines
cervesa
gominoles
jb
xampu
ramon@portatil:/directori$

Observem que redireccionem l'entrada de 'cat' amb la llista ja creada i construïm una pipe per unir la sortida de 'cat' amb l'entrada de 'sort' i acabem redireccionant la sortida a un nou fitxer. El que aconseguim és una llista ordenada, que si bé podíem haver fet el mateix amb 'sort < lista_compra > novallista' havia de fer-lo de l'altra forma per explicar-lo.

Grep

grep [opcions] expressió [llista de fitxers]

Grep és sens dubte, juntament amb l'ús de les pipes i la redirecció, una de les ordres amb més utilitat de linux i per extensió unix, encara que al principi ens costi de trobar la utilitat. Aquesta ordre és utilitzada per buscar expressions en un fitxer de text o una llista d'ells. Vegem un exemple simple:

ramon@portatil:/directori$ grep Xampu novallista
ramon@portatil:/directori$ grep xampu novallista
xampu
ramon@portatil:/directori$

Podeu observar que distingeix entre majúscules i minúscules, i que la sortida de l'ordre són totes aquelles línies que contenen l'expressió que volem. Veiem amb aquest senzill exemple com grep és una espècie de filtre que ens mostra únicament el que volem. Vegem altre exemple:

ramon@portatil:/directori$ cat llistadelacompra | grep o
gominoles
ramon@portatil:/directori$

Hem buscat dintre del llistat totes aquelles línies que continguin la lletra 'o'.

Si necessitéssim saber en quina línia del fitxer es troben, usaríem l'opció '-n':

ramon@portatil:/directori$ cat llistadelacompra | grep -n o
2:gominoles
ramon@portatil:/directori$

És evident la gran utilitat d'aquesta ordre quan necessitem cercar en un fitxer de configuració.

Per aconseguir l'efecte contrari de 'grep', és a dir, trobar totes les línies on no s'usi l'expressió, usarem l'opció '-v':

ramon@portatil:/directori$ cat llistadelacompra | grep a
xampu
cervesa
aspirines
ramon@portatil:/directori$
ramon@portatil:/directori$ cat llistadelacompra | grep -v a
gominoles
jb
ramon@portatil:/directori$
Exercicis

1. Buscar dintre del vostre directori personal els noms dels arxius que continguin la cadena 'gno'. Fer una llista amb els arxius i guardar-la en l'arxiu exercici1.txt

Solució 1:

ramon@portatil:$ ls -la > kk
ramon@portatil:$ grep gno kk > exercici1.txt
ramon@portatil:$ cat exercici1.txt
drwxr-xr-x 5 ramon ramon 4096 2005-04-01 16:09 .gnome
drwx------ 7 ramon ramon 4096 2005-04-04 21:52 .gnome2
drwx------ 2 ramon ramon 4096 2005-04-01 00:50 .gnome2private
-rw-r--r-- 1 ramon ramon 87 2005-04-01 00:12 .gtkrc-1.2-gnome2
ramon@portatil:$

Solució 2:

ramon@portatil:$ ls -la  | grep gno > exercici1.txt
ramon@portatil:$ cat exercici1.txt
drwxr-xr-x 5 ramon ramon 4096 2005-04-01 16:09 .gnome
drwx------ 7 ramon ramon 4096 2005-04-04 21:52 .gnome2
drwx------ 2 ramon ramon 4096 2005-04-01 00:50 .gnome2private
-rw-r--r-- 1 ramon ramon 87 2005-04-01 00:12 .gtkrc-1.2-gnome2
ramon@portatil:$

2. Buscar dintre dels directoris /etc /boot i /var/log aquells arxius que continguin la cadena 'debian' i guardar el resultat en l'arxiu exercici2.txt

Solució:

root@portatil:/ # grep debian /etc/* > /home/ramon/exercici2.txt
root@portatil:/ # grep debian /boot/* >> /home/ramon/exercici2.txt
root@portatil:/ # grep debian /var/log/* >> /home/ramon/exercici2.txt
root@portatil:/ # cat /home/ramon/exercici2.txt
/etc/bash.bashrc:if [ -z "$debianchroot" -a -r /etc/debianchroot ]; then
/etc/bash.bashrc: debianchroot=$(cat /etc/debianchroot)
/etc/bash.bashrc:PS1='${debianchroot:+($debianchroot)}\o@\h:\w\$ '
/etc/bash.bashrc:if [ -z "$debianchroot" -a -r /etc/debianchroot ]; then
/etc/bash.bashrc: debianchroot=$(cat /etc/debianchroot)
/etc/bash.bashrc:PS1='${debianchroot:+($debianchroot)}\o@\h:\w\$ '
/etc/bash.bashrcbackup:if [ -z "$debianchroot" -a -r /etc/debianchroot ]; the n
.......... (ometo part de la llista perquè no ocupi tant)...........
/var/log/scrollkeeper.log.1:abr 02 23:58:51 scrollkeeper-update: Registrant /us r/share/omf/debian-x-faq/debian-x-faq-C.omf
root@portatil:/ #

3. Idem exercici anterior però limitant a una única aparició.

Solució:

root@portatil:/ # grep -m1 debian /etc/* > /home/ramon/exercici3.txt
root@portatil:/ # grep -m1 debian /boot/* >> /home/ramon/exercici3.txt
root@portatil:/ # grep -m1 debian /var/log/* >> /home/ramon/exercici3.txt
root@portatil:/ # cat /home/ramon/exercici3.txt
/etc/bash.bashrc:if [ -z "$debianchroot" -a -r /etc/debianchroot ]; then
/etc/bash.bashrc:if [ -z "$debianchroot" -a -r /etc/debianchroot ]; then
/etc/bash.bashrcbackup:if [ -z "$debianchroot" -a -r /etc/debianchroot ]; then
/etc/bashcompletion: if [ -f /etc/debianversion ]; then
/etc/fdmount.conf:# Originally written by Tibor Simko <simko@debian.org> for gnuplot.
/etc/mailcap:application/x-debian-package; /usr/lib/acaroni/debian-view '%s'; needsterminal; description=Debian GNU/Linux Package; nametemplate=%s.deb
/etc/acaroni.types:# bug report) to acaroni-support@packages.debian.org if you would like new types
/etc/reportbug.conf:# header "X-Debbugs-CC: debian-qa@lists.debian.org"
/etc/services:# by IANA or llauri needed by a debian package.
/var/log/aptitude:[INSTALL] doc-debian
/var/log/base-config.log.1: dictionaries-common diveintopython doc-base doc-debian docbook
/var/log/scrollkeeper.log.1:abr 01 00:10:05 scrollkeeper-update: Registrant /usr/share/omf/debian-x-faq/debian-x-faq-C.omf
root@portatil:/ #

4. Fer una llista ordenada de tots els arxius del disc dur que tinguin l'extensió '.conf' i que en el seu interior continguin la paraula 'debian'.

Solució 1:

L'ordre hauria de ser grep -m1 -R --include=*.conf debian / > /home/ramon/exercici4.txt però l'he reduït al directori /etc perquè a més de trigar molt produeix errors en les tasques del directori /proc

root@portatil:/ # grep -m1 -R --include=*.conf debian /etc/* > /home/ramon/exercici4.txt
root@portatil:/ # cat /home/ramon/exercici4.txt
/etc/fdmount.conf:# Originally written by Tibor Simko <simko@debian.org> for gnuplot.
/etc/reportbug.conf:# header "X-Debbugs-CC: debian-qa@lists.debian.org"
/etc/udev/links.conf:# This file does not exist. Please do not ask the debian maintainer about it.
root@portatil:/ #

Solució 2:

Afegint els paràmetres -rIls --devices=skip ja no provoca errors quan analitza /proc i no contempla els dispositius. Aquesta és una solució molt millor que l'anterior.

root@portatil:/ # grep -rIls --devices=skip --include="*.conf" "debian" / > /home/ramon/exercici4.txt
root@portatil:/ # cat /home/ramon/exercici4.txt
/etc/fdmount.conf
/etc/reportbug.conf
/etc/udev/links.conf
/usr/share/apmd/apmd_proxy.conf
/proc/6804/task/6804/fd/13/fdmount.conf
/proc/6804/task/6804/fd/13/reportbug.conf
/proc/6804/task/6804/fd/13/udev/links.conf
/proc/6804/fd/13/fdmount.conf
/proc/6804/fd/13/reportbug.conf
/proc/6804/fd/13/udev/links.conf
/proc/7428/task/7428/fd/35/fdmount.conf
/proc/7428/task/7428/fd/35/reportbug.conf
/proc/7428/task/7428/fd/35/udev/links.conf
/proc/7428/fd/35/fdmount.conf
/proc/7428/fd/35/reportbug.conf
/proc/7428/fd/35/udev/links.conf
root@portatil:/home/ramon #

5. Fer una llista de tots els arxius del disc dur que s'executen amb sh. (Són aquells que en el seu interior continguin #! /bin/sh)

Solució 1:

L'ordre hauria de ser grep -m1 -R '#! /bin/sh' /* > /home/ramon/exercici5.txt però l'he reduït al directori /etc per la mateixa raó que en l'exercici anterior.

root@portatil:/ # grep -m1 -R '#! /bin/sh' /etc/* > /home/ramon/exercici5.txt
grep: /etc/xdg/menus/debian-menu.menu: No existe el fichero o el directorio
root@portatil:/ # cat /home/ramon/exercici5.txt
/etc/apm/event.d/anacron:#! /bin/sh
/etc/cron.daily/sysklogd:#! /bin/sh
/etc/cron.daily/slocate:#! /bin/sh
/etc/cron.daily/find.notslocate:#! /bin/sh
/etc/cron.monthly/scrollkeeper:#! /bin/sh
/etc/cron.weekly/sysklogd:#! /bin/sh
/etc/dbus-1/event.d/20hal:#! /bin/sh
/etc/init.d/makedev:#! /bin/sh
/etc/init.d/procps.sh:#! /bin/sh
/etc/init.d/halt:#! /bin/sh

.......... (ometo part de la llista perquè no ocupi tant)...........

/etc/udev/scripts/cdsymlinks.sh:#! /bin/sh -e
/etc/X11/rstart/commands/ListContexts:#! /bin/sh
/etc/X11/rstart/commands/ListGenericCommands:#! /bin/sh
/etc/X11/rstart/commands/x11r6/LoadMonitor:#! /bin/sh
/etc/X11/rstart/commands/x11r6/Terminal:#! /bin/sh
root@portatil:/ #

Solució 2:

Afegint els paràmetres -rIls --devices=skip ja no provoca errors quan analitza /proc i no contempla els dispositius. Aquesta és una solució molt millor que l'anterior.

root@portatil:/ # grep -rIls --devices=skip '#! /bin/sh' / > /home/ramon/exercici5.txt
root@portatil:/ # cat /home/ramon/exercici5.txt
/etc/pcmcia/network
/etc/cron.daily/sysklogd
/etc/cron.daily/slocate
/etc/cron.daily/find.notslocate
/etc/init.d/makedev
/etc/init.d/procps.sh
/etc/init.d/halt
/etc/init.d/reboot
/etc/init.d/single
/etc/init.d/mountvirtfs

.......... (ometo part de la llista perquè no ocupi tant)...........

/var/lib/dpkg/info/cupsys-bsd.postrm
/var/lib/dpkg/info/foomatic-filters-ppds.postinst
/var/lib/dpkg/info/x-ttcidfont-conf.config
/var/lib/dpkg/info/x-ttcidfont-conf.postinst
root@portatil:/ #

copyleft © 2014 ramon lopez
última actualització 16/09/14 17:23