Introdução à Linha de Comando Linux
1 Manipulando arquivos
1.1 O que é o Shell?
Tipicamente, quando interagimos com um computador, utilizamos graphical user interface (ou GUI), que funciona através de interações com o mouse.
É difícil fornecer instruções complexas para uma GUI, com muitos passos ou que envolvam várias operações sequenciais. Por exemplo, se você precisar copiar a terceira linha de mil arquivos de texto em centenas de diferentes diretórios.
Portanto, por fazerem tais atividades triviais, as interfaces de linha de comando (CLIs) são indispensáveis. Nesse contexto, temos o Shell, o programa onde o usuário digita comandos, que serão então executados e interpretados. O Shell mais popular hoje em dia, e presente em sistemas operacionais Unix, como o Linux, é o Bash.
1.3 Hello World!
Como todo curso de programação que se preze, vamos começar fazendo nosso ‘hello world’ em Shell:
echo 'Hello World!'
1.4 Comandos no shell
A maneira que interagimos com o shell é através de comandos digitados no prompt, que são então executados quando você pressiona a tecla Enter.
Mas você ainda não sabe nenhum comando! Então, para começarmos, use o comando ls
, que significa listar, que lista os arquivos na pasta, ou diretório, atual:
ls
1.5 Diretório de trabalho
O prompt listou todos os arquivos e diretórios presentes onde você está. Mas onde você está agora? Com o comando ‘pwd’, que significa Print Working Directory, você consegue ver o caminho absoluto para onde o seu prompt está apontando:
pwd
Se você seguiu as instruções à risca até aqui, o output do prompt deve ser o seu ‘Home Directory’, ou seja, o local que você entra quando faz login. Cada usuário no computador tem o seu próprio, e ele deve ter um formato /home/<USUARIO>
.
1.6 Movendo entre pastas
Agora, para se mover dentro do sistema de arquivos, você pode usar o comando ‘cd’, de change directory:
cd Downloads
Você entrou no diretório de downloads do seu computador. Você pode checar os arquivos existentes usando ‘ls’ e pode verificar onde está usando ‘pwd’.
ls
pwd
1.7 Opções do ls
Se você tem um grande número de arquivos no seu diretório, é complicado localizar algum arquivo apenas listando todos. Para isso, podemos usar alguns artifícios do comando ls:
ls -t #organiza por tempo em vez de ordem alfabética
ls -tr #reverte a ordem anterior (mostra o mais recente por último)
ls -s #mostra o tamanho de cada arquivo em blocos
ls -sh #mostra o tamanho de cada arquivo em formato de leitura humano
ls *.zip #mostra todos os arquivos que terminam com ".zip"
ls sh* #mostra todos os arquivos que começam com "sh"
ls *lesson* #mostra todos os arquivos que contém "lesson" em algum canto do nome
1.8 Dezipar arquivos
Agora que achamos o arquivo com os dados do curso, vamos dezipá-lo para acessar seu conteúdo interno:
unzip shell-lesson-data.zip
ls shell-lesson-data
cd shell-lesson-data
cd exercise-data
Dica: você não precisa escrever o nome do arquivo inteiro! Basta começar a escrever e pressionar ‘Tab’ que o prompt autocompletará.
1.10 Arquivos ocultos
Essa opção ‘..’ não está presente quando rodamos ‘ls’, mas ela está oculta em todos os diretórios e pode ser vista com:
ls -a
Assim como o ‘..’, que volta um passo na árvore de arquivos, também temos o ‘.’, que representa o diretório atual. Em algumas situações, também haverão alguns arquivos de configuração (como o .gitignore, comumente visto em repositórios do git).
1.11 Criar, mover, copiar e deletar arquivos
Para criar um diretório, você pode usar o comando ‘mkdir’, de make directory:
cd ../writing
mkdir thesis
ls
1.12 Regras básicas para nomear um diretório:
Não use espaços
Não comece com hífen (-)
Use apenas letras, números, ponto final, hífen, underscore
Se você precisa lidar com diretórios que não seguem essas regras, você pode colocar o nome deles entre aspas simples ’’ para mencioná-los em algum comando.
1.13 Criar um arquivo
Vamos criar um arquivo a partir do terminal:
cd thesis
touch draft.txt #cria arquivo sem abrir
mkdir files
cd files
code texto.txt #abre na IDE Visual Studio Code
nano rascunho.txt #abre no editor nano. Outras opções: vim, vi
1.14 Comandos do nano
Ctrl + O, Enter - salvar alterações no arquivo
Ctrl + X - sair do editor
Ctrl + ^ - modo de seleção de texto
Alt + 6 - copia
Ctrl + U - cola
1.15 Deletar arquivos
Como não vamos usar os arquivos criados em files, vamos removê-los usando ‘rm’, de remove:
rm texto.txt #deleta o arquivo
cd ..
rm files #irá retornar um erro
rm -rf files #para deletar um diretório e seus arquivos, é preciso das opções -rf (recursive,force)
#CUIDADO com esse comando! Não existe lixeira no Linux!!!!
1.16 Mover arquivos
O comando move é versátil e serve tanto para renomear arquivos quando para movê-los para outro caminho:
cd ~/Downloads/shell-lesson-data/exercise-data/writing #abrevia o caminho da Home
mv thesis/draft.txt thesis/quotes.txt #muda o nome de draft.txt para quotes.txt
ls thesis
mv thesis/quotes.txt . #movendo quotes.txt para o nosso diretório atual
ls thesis
1.17 Copiar arquivos
Podemos copiar arquivos usando o comando ‘cp’:
cp quotes.txt thesis/quotations.txt
cp -r thesis thesis_backup #podemos copiar recursivamente para gerar um arquivo de backup
ls thesis
ls thesis_backup
2 Fluxos de dados
2.1 Olhando para dentro dos arquivos
Agora que aprendemos a navegar diretórios, vamos mexer com arquivos. No diretório em que estamos, temos uma série de arquivos no formato Protein Data Bank (pdb). Vamos usar o comando ‘wc’, de word count:
wc cubane.pdb #linhas, palavras e caracteres no arquivo
wc -l #só linhas
2.2 Exibir conteúdo
Mas o que tem nesse arquivo?
cat cubane.pdb
Se o seu arquivo for muito grande, é melhor usar um exibidor interativo:
less cubane.pdb
2.3 Head e Tail
Às vezes, você só quer ver uma parte do arquivo. Você pode usar os comandos ‘head’ e ‘tail’:
head cubane.pdb
head -n 5 cubane.pdb
head -n 5 cubane.pdb ethane.pdb
tail cubane.pdb
tail -n 5 cubane.pdb
2.4 Redirecionamento
Podemos registar o output de um comando dentro de um arquivo por meio do símbolo ‘>’:
wc -l *.pdb > lengths.txt
cat lengths.txt
Agora, temos um arquivo chamado lengths.txt que possui o número de linhas de todos os arquivos .pdb do diretório.
2.5 Filtrar e ordenar os conteúdos de um arquivo
Nós podemos ordenar as linhas de um arquivo usando o comando ‘sort’:
sort -n lengths.txt
sort lengths.txt #nesse caso, o ordenamento será por ordem alfabética
E da mesma maneira, podemos direcionar o output do ordenamento para um novo arquivo:
sort -n lengths.txt > sorted-lengths.txt
head -n 1 sorted-lengths.txt
Obs.: em Shell, é uma péssima prática direcionar o output de uma operação para o mesmo arquivo, isso pode comprometer a integridade dele!
2.6 Passando o output para outro comando (pipe)
Em vez de criar vários arquivos intermediários que tornam o trabalho mais confuso, podemos direcionar o output de uma operação diretamente para outra usando o pipe ‘|’:
sort -n lengths.txt | head -n 1
wc -l *.pdb | sort -n | head -n 1
2.7 Exercício - Combinando múltiplos comandos
Volte ao Home Directory
Navegue até a pasta animal-counts, dentro de exercise-data e localize o arquivo animals.csv
Inspecione o arquivo. Quantas linhas ele tem? Qual o formato do dado dele?
Gere o arquivo exercicio.txt que ordena de forma alfabética reversa as 5 primeiras linhas do arquivo animals.txt e dispõe apenas os 3 últimos resultados da ordenação.
3 Loops & Scripts
3.1 Como repetir uma ação várias vezes?
Loops ou, em bom português, laços;
Como em qualquer outra linguagem, laços permitem que você realize uma mesma ação várias vezes, em sequência.
Mão na massa! Vamos supor que temos centenas de genomas, e queremos ver identificação de cada um desses bichos, que está na segunda linha de cada genoma. Você talvez pense em:
head -n 2 genoma.dat | tail -n 1
- Mas nós temos centenas de arquivos!
3.2 Introduzindo laços
- A estrutura geral de um laço simples em Bash é a seguinte:
# "para cada coisa na lista de coisas"
# coisa é um nome arbitrário!
for coisa in lista_de_coisas
# A palavra "do" indica o início do bloco
# da ação a ser realizada
do
# Não precisa indentar, mas ajuda.
comando_a_executar $coisa
# A palavra "done" indica o fim de um laço
done
3.3 Ok e agora para os genomas?
- Mesma coisa que antes, mas vamos usar dados “reais” agora:
for genoma in basilisk.dat minotaur.dat
do
head -n 2 $genoma | tail -n 1
done
- Ou, para saber a identificação para cada arquivo:
for genoma in basilisk.dat minotaur.dat
do
echo $genoma
head -n 2 $genoma | tail -n 1
done
3.4 Como salvar comandos para reutilizar depois?
- A resposta: Scripts!
- Arquivos de texto contendo código, que pode ser interpretado e re-executado múltiplas vezes.
- Vamos supor que novos genomas continuam entrando no seu banco de dados, e agora você quer uma forma fácil de re-executar a identificação do genoma.
- Vamos então fazer um script que execute os comandos anteriores.
3.5 Escrevendo um script
Existem inúmeros editores de texto possíveis, mas, se você está restrito à linha de comando, provavelmente usará:
nano
vim
Para motivos didáticos, utilizaremos o
nano
nos exemplos posteriores.Vamos criar um novo script, para isso, execute:
nano identifica_genoma.sh
3.6 Escrevendo um script
- Dentro do script, vamos colocar o comando anterior, mas vamos substituir uma parte:
head -n 2 $1 | tail -n 1
A variável
$1
indica o primeiro argumento na linha de comando quando esse script é executado, ou seja, o genoma. Também podemos usar$2
,$3
, etc…$@
se refere a todos os argumentos.Salve o arquivo, e agora podemos executá-lo como tal:
bash identifica_genoma.sh unicorn.dat
3.7 Uma breve tangente: Interpretadores e permissões
Você notou como usamos
bash
no comando anterior? Isso é um comando por si só, que diz que a linguagembash
deve interpretar o conteúdo textual do arquivo.Mas isso pode ser ainda mais simples! Com apenas dois passos:
- Inclua no seu arquivo um shebang:
#!/bin/bash head -n 2 $1 | tail -n 1
3.8 Ok, mas e agora para executar?
- Agora para executar seu programa propriamente dito, precisamos primeiro mudar suas permissões:
- O comando
chmod
pode dar a qualquer arquivo de texto a capacidade de ser executado - Isso serve não só para bash, mas também Python, R, etc.
- O comando
chmod +x identifica_genoma.sh
- Agora podemos executar nosso script, com interpretadores e argumentos claramente definidos, assim:
./identifica_genoma.sh unicorn.dat
- Nosso script agora virou um comando! Podendo ser utilizado em outros scripts!
3.9 Exercício
Se direcione ao diretório
exercise-data/alkanes
Lá, escreva um script chamado
junta_pdb.sh
. Esse script deve fazer um laço em todos os arquivos .pdb no diretório atual, concat
enando todos eles em um único arquivo. Para isso, use o direcionador de saída>>
.Faça seu script executável (adicione o shebang e modifique as permissões).
4 Avançando nos comandos I - Grep e Expressões Regulares
4.1 O que danado é grep?
Global Regular Expression search and Print
Uma forma de achar padrões em arquivo de texto
- Que padrões são esses? Expressões regulares.
Um uso comum de grep:
# Buscar a palavra "Equus" em todos os arquivos .dat grep Equus *.dat
No entanto, grep se torna realmente poderoso quando usamos expressões regulares
4.2 O que são expressões regulares?
São formas de definir padrões de busca textual regrados.
Por exemplo, uma expressão regular para achar a palavra “Nossa” seria apenas a palavra propriamente dita. Mas para buscar “Nossa”, “Nosso”, “Nossas”, “Nossos”, você faria algo assim:
Noss[a-zA-Z]*
- Por exemplo com grep:
grep "Noss[a-zA-Z]*" cancao_do_exilio.txt
4.3 Expressões regulares
- Expressões regulares (ou regexes), podem ficar ainda mais complexas!
# Expressão regular para buscar um email numa sequência de texto
grep -E '\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b' texto.txt
- Não cobriremos grep e expressões regulares a fundo aqui, mas saiba que são essenciais para qualquer pessoa trabalhando na linha de comando, sobretudo para bioinformatas.
- Esse site possui um tutorial interativo de regex caso queira aprender mais a respeito.
4.4 Mais sobre grep
- O que mostramos aqui sobre grep é apenas o básico, grep pode ficar, assim como as regexes, ainda mais complexo! Dê uma olhada no seu manual (
man grep
) para saber mais a respeito. Mas aqui uma palhinha:- Vamos contar o número de ocorrências da palavra “terra” na Canção do Exílio:
grep -c terra cancao_do_exilio.txt
5 Avançando nos comandos II
5.1 xargs
xargs
é um comando que transforma a saída de outros comandos de forma a facilitar a execução encadeada. Pois a quebra de linhas ou espaços pode dificultar a execução de outro comando em sequência.
# Isso não funciona
ls *pdb | grep AUTHOR
# Isso funciona!
ls *pdb | xargs grep AUTHOR
5.2 GNU parallel
parallel
é um comando que por padrão não vem em algumas distribuições, mas é super útil! Use ele para paralelizar a execução de comandos.Por exemplo, vamos compactar vários arquivos .pdb:
ls *pdb | parallel gzip
