<Anterior | Contenido | Siguiente>
Comandos de grupo y subcapas
golpear permite agrupar los comandos. Esto se puede hacer de dos formas; ya sea con un comando de grupo o con un subshell. A continuación, se muestran ejemplos de la sintaxis de cada uno:
Comando de grupo:
{comando1; command2; [comando3; ...]}
Subcapa:
(comando1; comando2; [comando3; ...])
Las dos formas difieren en que un comando de grupo rodea sus comandos con llaves y una subcapa usa paréntesis. Es importante señalar que, debido a la forma golpear implementa comandos de grupo, las llaves deben estar separadas de los comandos por un espacio y el último comando debe terminar con un punto y coma o una nueva línea antes de la llave de cierre.
Entonces, ¿para qué sirven los comandos de grupo y las subcapas? Si bien tienen una diferencia importante (a la que llegaremos en un momento), ambos se utilizan para gestionar la redirección. Consideremos un segmento de secuencia de comandos que realiza redirecciones en varios comandos:
ls -l> salida.txt
echo "Listado de foo.txt" >> salida.txt cat foo.txt >> salida.txt
ls -l> salida.txt
echo "Listado de foo.txt" >> salida.txt cat foo.txt >> salida.txt
Esto es bastante sencillo. Tres comandos con su salida redirigida a un archivo llamado salida.txt. Usando un comando de grupo, podríamos codificar esto de la siguiente manera:
{ls -l; echo "Listado de foo.txt"; gato foo.txt; }> salida.txt
{ls -l; echo "Listado de foo.txt"; gato foo.txt; }> salida.txt
El uso de una subcapa es similar:
(ls -l; echo "Listado de foo.txt"; cat foo.txt)> salida.txt
(ls -l; echo "Listado de foo.txt"; cat foo.txt)> salida.txt
Usando esta técnica, nos hemos ahorrado algo de tipeo, pero donde un comando de grupo o subshell realmente brilla es con pipelines. Al construir una canalización de comandos, a menudo es útil combinar los resultados de varios comandos en una sola secuencia. Los comandos de grupo y las subcapas lo hacen fácil:
{ls -l; echo "Listado de foo.txt"; gato foo.txt; } | lpr
{ls -l; echo "Listado de foo.txt"; gato foo.txt; } | lpr
Aquí hemos combinado la salida de nuestros tres comandos y los hemos conectado a la entrada de lpr para producir un informe impreso.
En el script que sigue, usaremos comandos de grupos y veremos varias técnicas de programación que se pueden emplear junto con matrices asociativas. Este guión, llamado matriz-2, cuando se le da el nombre de un directorio, imprime una lista de los archivos en el directorio junto con los nombres del propietario del archivo y del propietario del grupo. Al final de la lista, el script imprime un recuento de la cantidad de archivos que pertenecen a cada propietario y grupo. Aquí vemos los resultados (condensados por brevedad) cuando se le da al script el directorio
/ usr / bin:
[yo @ linuxbox ~] $ matriz-2 / usr / bin | ||
/usr/bin/2to3-2.6 | raíz | raíz |
/ usr / bin / 2to3 | raíz | raíz |
/ usr / bin / a2p | raíz | raíz |
/ usr / bin / abrowser | raíz | raíz |
/ usr / bin / aconnect | raíz | raíz |
/ usr / bin / acpi_fakekey | raíz | raíz |
/ usr / bin / acpi_listen | raíz | raíz |
/ usr / bin / add-apt-repository | raíz | raíz |
. | ||
. | ||
. | ||
/ usr / bin / zipgrep | raíz | raíz |
/ usr / bin / zipinfo | raíz | raíz |
/ usr / bin / zipnote | raíz | raíz |
/ usr / bin / zip | raíz | raíz |
/ usr / bin / zipsplit / usr / bin / zjsdecode / usr / bin / zsoelim | raíz raíz raíz | raíz raíz raíz | |
Propietarios de archivos: demonio: 1 | archivo (s) | ||
raíz: 1394 | archivo (s) |
Propietarios del grupo de archivos: crontab: 1 archivo (s) demonio: 1 archivo (s) lpadmin: 1 archivo (s) correo: 4 archivo (s) mlocate: 1 archivo (s) raíz: 1380 archivo (s) sombra: 2 archivo (s) ssh: 1 archivo (s)
tty: 2 archivo (s)
utmp: 2 archivo (s)
#! / Bin / bash
#! / Bin / bash
# array-2: use matrices para contar los propietarios de archivos
declare -A files file_group file_owner grupos propietarios si [[! -d "$ 1"]]; luego
echo "Uso: array-2 dir"> & 2 salir 1
fi
para i en "$ 1" / *; do owner = $ (stat -c% U "$ i") group = $ (stat -c% G "$ i") archivos ["$ i"] = "$ i" file_owner ["$ i"] = $ propietario file_group ["$ i"] = $ grupo ((++ propietarios [$ propietario])) ((++ grupos [$ grupo]))
done
# Enumere los archivos recopilados
{para i en "$ {archivos [@]}"; imprimirf "% -40s% -10s% -10s \ n" \
"$ i" $ {propietario_archivo ["$ i"]} $ {grupo_archivos ["$ i"]} hecho} | clasificar
# array-2: use matrices para contar los propietarios de archivos
declare -A files file_group file_owner grupos propietarios si [[! -d "$ 1"]]; luego
echo "Uso: array-2 dir"> & 2 salir 1
fi
para i en "$ 1" / *; do owner = $ (stat -c% U "$ i") group = $ (stat -c% G "$ i") archivos ["$ i"] = "$ i" file_owner ["$ i"] = $ propietario file_group ["$ i"] = $ grupo ((++ propietarios [$ propietario])) ((++ grupos [$ grupo]))
done
# Enumere los archivos recopilados
{para i en "$ {archivos [@]}"; imprimirf "% -40s% -10s% -10s \ n" \
"$ i" $ {propietario_archivo ["$ i"]} $ {grupo_archivos ["$ i"]} hecho} | clasificar
Aquí hay una lista (con números de línea) del script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
27
28
29
30
31
32
33
34
35
36
37
38
39
40
echo
echo
# Propietarios de listas
echo "Propietarios de archivos:"
{para i en "$ {! propietarios [@]}"; hacer
printf "% -10s:% 5d archivo (s) \ n" "$ i" $ {propietarios ["$ i"]} hecho} | clasificar
echo
# Lista de grupos
echo "Propietarios del grupo de archivos:"
{para i en "$ {! grupos [@]}"; hacer
printf "% -10s:% 5d archivo (s) \ n" "$ i" $ {grupos ["$ i"]} hecho} | clasificar
# Propietarios de listas
echo "Propietarios de archivos:"
{para i en "$ {! propietarios [@]}"; hacer
printf "% -10s:% 5d archivo (s) \ n" "$ i" $ {propietarios ["$ i"]} hecho} | clasificar
echo
# Lista de grupos
echo "Propietarios del grupo de archivos:"
{para i en "$ {! grupos [@]}"; hacer
printf "% -10s:% 5d archivo (s) \ n" "$ i" $ {grupos ["$ i"]} hecho} | clasificar
Echemos un vistazo a la mecánica de este script:
Línea 5: Las matrices asociativas deben crearse con el declarar comando usando el -A
opción. En este script creamos cinco matrices de la siguiente manera:
files contiene los nombres de los archivos en el directorio, indexado por nombre de archivo file_group contiene el propietario del grupo de cada archivo, indexado por nombre de archivo file_owner contiene el propietario de cada archivo, indexado por grupos de nombre de archivo contiene el número de archivos que pertenecen a los propietarios del grupo indexado contiene el número de archivos que pertenecen al propietario indexado
Líneas 7-10: Comprueba que se haya pasado un nombre de directorio válido como parámetro posicional. De lo contrario, se muestra un mensaje de uso y el script sale con un estado de salida de 1.
Líneas 12-20: Recorra los archivos del directorio. Utilizando el stat comando, las líneas 13 y 14 extraen los nombres del propietario del archivo y del propietario del grupo y asignan los valores a sus respectivas matrices (líneas 16, 17) utilizando el nombre del archivo como índice de la matriz. Del mismo modo, el nombre del archivo se asigna a la archivos matriz (línea 15).
Líneas 18-19: el número total de archivos que pertenecen al propietario del archivo y al propietario del grupo se incrementa en uno.
Líneas 22-27: Se emite la lista de archivos. Esto se hace usando la expansión del parámetro "$ {array [@]}" que se expande en la lista completa de elementos del array con cada elemento tratado como una palabra separada. Esto permite la posibilidad de que un nombre de archivo contenga espacios incrustados. También tenga en cuenta que todo el bucle está encerrado entre llaves, formando así un comando de grupo. Esto permite que toda la salida del bucle se canalice al sort mando. Esto es necesario porque la expansión de los elementos de la matriz no está ordenada.
Líneas 29-40: Estos dos bucles son similares al bucle de lista de archivos, excepto que usan el "$ {!
matriz [@]} "expansión que se expande en la lista de índices de matriz en lugar de la lista de elementos de matriz.