Se estás cansado dos teus scripts Bash a demorarem uma eternidade para correr, este tutorial é para ti. Muitas vezes, podes executar scripts Bash em paralelo, o que pode acelerar dramaticamente o resultado. Como? Utilizando a utilidade GNU Parallel, também chamada apenas de Parallel, com alguns exemplos úteis do GNU Parallel!
O Parallel executa scripts Bash em paralelo através de um conceito chamado multi-threading. Esta utilidade permite executar diferentes tarefas por CPU em vez de apenas uma, reduzindo o tempo para executar um script.
Neste tutorial, vais aprender a executar scripts Bash em multi-threading com toneladas de excelentes exemplos do GNU Parallel!
Pré-requisitos
Este tutorial estará repleto de demonstrações práticas. Se pretendes acompanhar, certifica-te de que tens o seguinte:
- A Linux computer. Any distribution will work. The tutorial uses Ubuntu 20.04 running on Windows Subsystem for Linux (WSL).
- Sessão iniciada com um utilizador com privilégios sudo.
Instalar o GNU Parallel
Para começar a acelerar os scripts Bash com multi-threading, primeiro tens de instalar o Parallel. Então, vamos começar por descarregar e instalá-lo.
1. Abre um terminal Bash.
2. Executa wget
para descarregar o pacote Parallel. O comando abaixo descarrega a última versão (parallel-latest
) para o diretório de trabalho atual.
Se preferir usar uma versão mais antiga do GNU Parallel, você pode encontrar todos os pacotes no site oficial de download.
3. Agora, execute o comando tar abaixo para descompactar o pacote que acabou de baixar.
Abaixo, o comando usa a bandeira x
para extrair o arquivo, j
para especificar que ele se destina a um arquivo com extensão .bz2
, e f
para aceitar um arquivo como entrada para o comando tar. sudo tar -xjf parallel-latest.tar.bz2
Agora você deve ter um diretório chamado parallel- com o mês, dia e ano do último lançamento.
4. Navegue até a pasta do arquivo de arquivamento com cd
. Neste tutorial, a pasta do arquivo de arquivamento é chamada de parallel-20210422, como mostrado abaixo.

5. Em seguida, construa e instale o binário GNU Parallel executando os seguintes comandos:
Agora, verifique se o Parallel foi instalado corretamente verificando a versão instalada.

Ao executar o Parallel pela primeira vez, você também pode ver algumas linhas assustadoras que exibem texto como
perl: warning:
. Essas mensagens de aviso indicam que o Parallel não consegue detectar suas configurações atuais de localidade e idioma. Mas não se preocupe com esses avisos por enquanto. Você aprenderá como corrigir esses avisos mais tarde.
Configurando o GNU Parallel
Agora que o Parallel está instalado, você pode usá-lo imediatamente! No entanto, é importante configurar algumas configurações antes de começar.
Enquanto ainda estiver no seu terminal Bash, concorde com a permissão de pesquisa acadêmica do GNU Parallel research permission, informando ao Parallel que você o citará em qualquer pesquisa acadêmica, especificando o parâmetro citation
seguido por will cite
.
Se você não deseja apoiar o GNU ou seus mantenedores, concordar em citar não é obrigatório para usar o GNU Parallel.
Altere a localidade definindo as seguintes variáveis de ambiente executando as linhas de código abaixo. Definir variáveis de ambiente de localidade e idioma como esta não é um requisito. Mas o GNU Parallel verifica a presença delas sempre que é executado.
Se as variáveis de ambiente não existirem, o Parallel reclamará sobre elas toda vez, como você viu na seção anterior.
Este tutorial assume que você é um falante de inglês. Outros idiomas são suportados também.

Executando Comandos de Shell Ad-Hoc
Vamos agora começar a usar o GNU Parallel! Para começar, você aprenderá a sintaxe básica. Uma vez que esteja confortável com a sintaxe, você entrará em alguns exemplos úteis do GNU Parallel mais tarde.
Para começar, vamos abordar um exemplo super simples de simplesmente ecoar os números de 1 a 5.
1. No seu terminal Bash, execute os seguintes comandos. Empolgante, certo? O Bash usa o comando echo para enviar os números de 1 a 5 para o terminal. Se você colocasse cada um desses comandos em um script, o Bash executaria cada um sequencialmente, aguardando o término do anterior.
Neste exemplo, você está executando cinco comandos que não levam quase nenhum tempo. Mas, imagine se esses comandos fossem scripts Bash que realmente fizessem algo útil, mas levassem uma eternidade para serem executados?
Agora, execute cada um desses comandos ao mesmo tempo com o Parallel como abaixo. Neste exemplo, o Parallel executa o comando echo e, designado pelo :::
, passa esse comando os argumentos, 1
, 2
, 3
, 4
, 5
. Os três dois-pontos indicam ao Parallel que você está fornecendo entrada via linha de comando em vez do pipeline (mais sobre isso depois).
No exemplo abaixo, você passou um único comando para o Parallel sem opções. Aqui, como todos os exemplos do Parallel, o Parallel iniciou um novo processo para cada comando usando um núcleo de CPU diferente.
Todos os comandos do Parallel seguem a sintaxe
parallel [Opções] <Comando para multithreading>
.
3. Para demonstrar o recebimento paralelo de entrada do pipeline Bash, crie um arquivo chamado count_file.txt como abaixo. Cada número representa o argumento que você passará para o comando echo.
4. Agora, execute o comando cat
para ler esse arquivo e passe a saída para o Parallel, conforme mostrado abaixo. Neste exemplo, o {}
representa cada argumento (1-5) que será passado para o Parallel.

Comparando Bash e GNU Parallel
Agora, usar o Parallel pode parecer apenas uma maneira complicada de executar comandos Bash. Mas o benefício real para você é a economia de tempo. Lembre-se, o Bash será executado em apenas um núcleo da CPU, enquanto o GNU Parallel será executado em vários ao mesmo tempo.
1. Para demonstrar a diferença entre comandos sequenciais Bash vs. Parallel, crie um script Bash chamado test.sh com o seguinte código. Crie este script no mesmo diretório em que você criou o count_file.txt anteriormente.
O script Bash abaixo lê o arquivo count_file.txt, espera por 1, 2, 3, 4 e 5 segundos, exibe o comprimento da espera no terminal e termina.
2. Agora, execute o script usando o comando time
para medir quanto tempo o script leva para ser concluído. Levará 15 segundos.
3. Agora, use o comando time
novamente para realizar a mesma tarefa, mas desta vez use o Parallel para fazê-lo.
O comando abaixo realiza a mesma tarefa, mas desta vez, em vez de esperar o primeiro loop ser concluído antes de iniciar o próximo, ele será executado em cada núcleo da CPU e iniciará o máximo possível ao mesmo tempo.

Conheça o Teste de Execução!
Agora é hora de entrar em alguns exemplos mais práticos do GNU Parallel. Mas, antes de fazer isso, você deve primeiro conhecer a sinalização --dryrun
. Esta sinalização é útil quando você deseja ver o que acontecerá sem o Parallel realmente fazê-lo.
A bandeira --dryrun
pode ser a verificação final de sanidade antes de executar um comando que não se comporta como você pensava. Infelizmente, se você inserir um comando que possa prejudicar o seu sistema, a única coisa que o GNU Parallel irá ajudá-lo a fazer é prejudicá-lo mais rápido!
Exemplo do GNU Parallel #1: Baixando Arquivos da Web
Para esta tarefa, você irá baixar uma lista de arquivos de várias URLs na web. Por exemplo, essas URLs podem representar páginas da web que você deseja salvar, imagens ou até mesmo uma lista de arquivos de um servidor FTP.
Para este exemplo, você vai baixar uma lista de pacotes de arquivo (e os arquivos SIG) do servidor FTP do GNU parallel.
1. Crie um arquivo chamado download_items.txt, pegue alguns links de download do site de download oficial e adicione-os ao arquivo separados por uma nova linha.
Você poderia economizar algum tempo usando a biblioteca Beautiful Soup do Python para extrair todos os links da página de download.
2. Leia todas as URLs do arquivo download_items.txt e passe-as para o Parallel, que invocará o wget
e passará cada URL.
Não se esqueça de que
{}
em um comando paralelo é um espaço reservado para a string de entrada!
3. Talvez você precise controlar o número de threads que o GNU Parallel usa de uma vez. Se for o caso, adicione o parâmetro --jobs
ou -j
ao comando. O parâmetro --jobs
limita o número de threads que podem ser executadas simultaneamente para o número que você especificar.
Por exemplo, para limitar o Parallel a baixar cinco URLs de cada vez, o comando ficaria assim:
O parâmetro
--jobs
no comando acima pode ser ajustado para baixar qualquer número de arquivos, desde que o computador em que você está executando tenha CPUs suficientes para processá-los.
4. Para demonstrar o efeito do parâmetro --jobs
, ajuste agora a contagem de trabalhos e execute o comando time
para medir quanto tempo cada execução leva.
Exemplo do GNU Parallel #2: Descompactando Pacotes de Arquivos
Agora que você baixou todos esses arquivos de arquivamento do exemplo anterior, agora você deve descompactá-los.
Enquanto estiver no mesmo diretório dos pacotes de arquivos, execute o seguinte comando Parallel. Observe o uso do caractere curinga (*
). Como este diretório contém tanto pacotes de arquivos quanto os arquivos SIG, você deve dizer ao Parallel para processar apenas os arquivos .tar.bz2.
Bônus! Se estiver usando o GNU parallel interativamente (não em um script), adicione a flag --bar
para que o Parallel mostre uma barra de progresso enquanto a tarefa está em execução.

--bar
flagExemplo do GNU Parallel #3: Removendo Arquivos
Se você seguiu os exemplos um e dois, agora deve ter muitas pastas no seu diretório de trabalho ocupando espaço. Então vamos remover todos esses arquivos em paralelo!
Para remover todas as pastas que começam com parallel- usando o Parallel, liste todas as pastas com ls -d
e encaminhe cada um dos caminhos das pastas para o Parallel, invocando rm -rf
em cada pasta, como mostrado abaixo.
Lembre-se da flag
--dryrun
!
Conclusão
Agora você pode automatizar tarefas com o Bash e economizar muito tempo. O que você escolhe fazer com esse tempo depende de você. Se economizar tempo significa sair um pouco mais cedo do trabalho ou ler outro post no blog ATA, é tempo de volta no seu dia.
Agora pense em todos os scripts de longa duração em seu ambiente. Quais deles você pode acelerar com o Parallel?
Source:
https://adamtheautomator.com/how-to-speed-up-bash-scripts-with-multithreading-and-gnu-parallel/