<Anterior | Conteúdo | Próxima>
Comandos de grupo e subshells
bater permite que os comandos sejam agrupados. Isso pode ser feito de um desses dois jeitos; qualquer um com um comando de grupo ou com um subcamada. Aqui estão alguns exemplos da sintaxe de cada um:
Comando de grupo:
{command1; command2; [command3; ...]}
Subcamada:
(comando1; comando2; [comando3; ...])
As duas formas diferem porque um comando de grupo envolve seus comandos com colchetes e um subshell usa parênteses. É importante notar que, devido à forma como bater implementa comandos de grupo, as chaves devem ser separadas dos comandos por um espaço e o último comando deve terminar com um ponto e vírgula ou uma nova linha antes da chave de fechamento.
Então, para que servem os comandos de grupo e subshells? Embora tenham uma diferença importante (que veremos em breve), ambos são usados para gerenciar o redirecionamento. Vamos considerar um segmento de script que executa redirecionamentos em vários comandos:
ls -l> output.txt
echo "Listagem de foo.txt" >> output.txt cat foo.txt >> output.txt
ls -l> output.txt
echo "Listagem de foo.txt" >> output.txt cat foo.txt >> output.txt
Isso é muito simples. Três comandos com sua saída redirecionada para um arquivo chamado output.txt. Usando um comando de grupo, poderíamos codificar isso da seguinte maneira:
{ls -l; echo "Listagem de foo.txt"; cat foo.txt; }> output.txt
{ls -l; echo "Listagem de foo.txt"; cat foo.txt; }> output.txt
Usar um subshell é semelhante:
(ls -l; echo "Listagem de foo.txt"; cat foo.txt)> output.txt
(ls -l; echo "Listagem de foo.txt"; cat foo.txt)> output.txt
Usando essa técnica, economizamos um pouco de digitação, mas onde um comando de grupo ou subshell realmente brilha é com pipelines. Ao construir um pipeline de comandos, geralmente é útil combinar os resultados de vários comandos em um único fluxo. Comandos de grupo e subshells tornam isso fácil:
{ls -l; echo "Listagem de foo.txt"; cat foo.txt; } | lpr
{ls -l; echo "Listagem de foo.txt"; cat foo.txt; } | lpr
Aqui, combinamos a saída de nossos três comandos e os direcionamos para a entrada de lpr para produzir um relatório impresso.
No script a seguir, usaremos comandos de grupos e examinaremos várias técnicas de programação que podem ser empregadas em conjunto com matrizes associativas. Este script, chamado matriz-2, quando recebe o nome de um diretório, imprime uma lista dos arquivos no diretório junto com os nomes do proprietário do arquivo e do proprietário do grupo. No final da listagem, o script imprime uma contagem do número de arquivos pertencentes a cada proprietário e grupo. Aqui, vemos os resultados (condensados para brevidade) quando o script recebe o diretório
/ usr / bin:
[me @ linuxbox ~] $ array-2 / usr / bin | ||
/usr/bin/2to3-2.6 | raiz | raiz |
/ usr / bin / 2to3 | raiz | raiz |
/ usr / bin / a2p | raiz | raiz |
/ usr / bin / abrowser | raiz | raiz |
/ usr / bin / aconnect | raiz | raiz |
/ usr / bin / acpi_fakekey | raiz | raiz |
/ usr / bin / acpi_listen | raiz | raiz |
/ usr / bin / add-apt-repository | raiz | raiz |
. | ||
. | ||
. | ||
/ usr / bin / zipgrep | raiz | raiz |
/ usr / bin / zipinfo | raiz | raiz |
/ usr / bin / zipnote | raiz | raiz |
/ usr / bin / zip | raiz | raiz |
/ usr / bin / zipsplit / usr / bin / zjsdecode / usr / bin / zsoelim | raiz raiz raiz | raiz raiz raiz | |
Proprietários de arquivo: daemon: 1 | arquivos) | ||
root: 1394 | arquivos) |
Proprietários do grupo de arquivos: crontab: 1 arquivo (s) daemon: 1 arquivo (s) lpadmin: 1 arquivo (s) mail: 4 arquivo (s) mlocate: 1 arquivo (s) root: 1380 arquivo (s) sombra: 2 arquivo (s) ssh: 1 arquivo (s)
tty: 2 arquivo (s)
utmp: 2 arquivo (s)
#! / Bin / bash
#! / Bin / bash
# array-2: Use arrays para registrar os proprietários dos arquivos
declara -A arquivos file_group file_owner grupos proprietários if [[! -d "$ 1"]]; então
echo "Uso: array-2 dir"> & 2 exit 1
fi
para i em "$ 1" / *; do owner = $ (stat -c% U "$ i") group = $ (stat -c% G "$ i") files ["$ i"] = "$ i" file_owner ["$ i"] = $ proprietário file_group ["$ i"] = $ group ((++ proprietários [$ owner])) ((++ grupos [$ group]))
feito
# Liste os arquivos coletados
{ para i em "${arquivos[@]}"; faça printf "%-40s %-10s %-10s\n"
"$ i" $ {file_owner ["$ i"]} $ {file_group ["$ i"]} feito} | ordenar
# array-2: Use arrays para registrar os proprietários dos arquivos
declara -A arquivos file_group file_owner grupos proprietários if [[! -d "$ 1"]]; então
echo "Uso: array-2 dir"> & 2 exit 1
fi
para i em "$ 1" / *; do owner = $ (stat -c% U "$ i") group = $ (stat -c% G "$ i") files ["$ i"] = "$ i" file_owner ["$ i"] = $ proprietário file_group ["$ i"] = $ group ((++ proprietários [$ owner])) ((++ grupos [$ group]))
feito
# Liste os arquivos coletados
{ para i em "${arquivos[@]}"; faça printf "%-40s %-10s %-10s\n"
"$ i" $ {file_owner ["$ i"]} $ {file_group ["$ i"]} feito} | ordenar
Aqui está uma lista (com números de linha) do 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
eco
eco
# Proprietários da lista
echo "Proprietários de arquivos:"
{para i em "$ {! owners [@]}"; Faz
printf "% -10s:% 5d arquivo (s) \ n" "$ i" $ {owners ["$ i"]} feito} | ordenar
eco
# Listar grupos
echo "Proprietários de grupos de arquivos:"
{para i em "$ {! grupos [@]}"; Faz
printf "% -10s:% 5d arquivo (s) \ n" "$ i" $ {grupos ["$ i"]} feito} | ordenar
# Proprietários da lista
echo "Proprietários de arquivos:"
{para i em "$ {! owners [@]}"; Faz
printf "% -10s:% 5d arquivo (s) \ n" "$ i" $ {owners ["$ i"]} feito} | ordenar
eco
# Listar grupos
echo "Proprietários de grupos de arquivos:"
{para i em "$ {! grupos [@]}"; Faz
printf "% -10s:% 5d arquivo (s) \ n" "$ i" $ {grupos ["$ i"]} feito} | ordenar
Vamos dar uma olhada na mecânica deste script:
Linha 5: Matrizes associativas devem ser criadas com o declarar comando usando o -A
opção. Neste script, criamos cinco matrizes da seguinte maneira:
arquivos contém os nomes dos arquivos no diretório, indexados por nome de arquivo file_group contém o proprietário do grupo de cada arquivo, indexado por nome de arquivo file_owner contém o proprietário de cada arquivo, indexado por grupos de nomes de arquivo contém o número de arquivos pertencentes aos proprietários de grupos indexados contém o número de arquivos pertencentes ao proprietário indexado
Linhas 7-10: Verifica se um nome de diretório válido foi passado como um parâmetro posicional. Caso contrário, uma mensagem de uso é exibida e o script sai com um status de saída 1.
Linhas 12-20: Percorra os arquivos no diretório. Usando o estado as linhas 13 e 14 extraem os nomes do proprietário do arquivo e do proprietário do grupo e atribuem os valores às suas respectivas matrizes (linhas 16, 17) usando o nome do arquivo como índice da matriz. Da mesma forma, o próprio nome do arquivo é atribuído ao arquivos array (linha 15).
Linhas 18-19: O número total de arquivos pertencentes ao proprietário do arquivo e ao proprietário do grupo é incrementado em um.
Linhas 22-27: A lista de arquivos é gerada. Isso é feito usando a expansão do parâmetro "$ {array [@]}", que se expande em toda a lista de elementos do array, com cada elemento tratado como uma palavra separada. Isso permite a possibilidade de um nome de arquivo conter espaços incorporados. Observe também que todo o loop está entre colchetes, formando assim um comando de grupo. Isso permite que toda a saída do loop seja canalizada para o tipo comando. Isso é necessário porque a expansão dos elementos da matriz não é classificada.
Linhas 29-40: Esses dois loops são semelhantes ao loop da lista de arquivos, exceto que eles usam o "$ {!
array [@]} "expansão que se expande para a lista de índices de array em vez da lista de elementos de array.