Mão na massa · ~28 min
Coringas, busca e manipulação em lote
Hoje você monta uma estrutura de teste, aprende a técnica de segurança que evita apagar o que não devia, manipula dezenas de arquivos com um comando só, e termina usando os mesmos comandos dentro de um container.
⏱️ Prática mais curta hoje
Como a primeira parte da aula foi a N1 da 2ª etapa, sobra menos tempo de laboratório. Se não conseguir concluir todos os passos em aula, termine fora dela — este roteiro é suficiente pra você seguir sozinho, e as observações podem ser preenchidas depois.
Passo 1 de 6
Montando uma estrutura de teste
mkdir -p ~/lab12/logs && cd ~/lab12 && touch relatorio{1..5}.txt sistema{1..3}.log notas.mdO que é
mkdir -p cria o diretório e os pais que faltarem. O {1..5} é expansão de chaves: o shell gera relatorio1.txt até relatorio5.txt automaticamente.
Por que importa
Nove arquivos criados com um comando só, em vez de nove touch separados. Atenção: isso ainda não é coringa. As chaves inventam nomes, existam os arquivos ou não; o coringa do passo 2 só casa com arquivos que já existem.
$ mkdir -p ~/lab12/logs && cd ~/lab12 && touch relatorio{1..5}.txt sistema{1..3}.log notas.md $ ls logs notas.md relatorio1.txt relatorio2.txt relatorio3.txt relatorio4.txt relatorio5.txt sistema1.log sistema2.log sistema3.log
nove arquivos e um diretório logs vazio. Trabalhe sempre dentro de ~/lab12 nos próximos passos — assim nenhum comando de hoje toca seus arquivos pessoais.
Passo 2 de 6
A técnica de segurança: veja antes de agir
echo *.log e ls *.txtO que é
Quem expande o coringa é o shell, antes do comando rodar. Então echo mostra exatamente a lista que qualquer outro comando receberia.
Por que importa
É a diferença entre apagar o que você quis e apagar o que você não percebeu que casava com o padrão.
$ echo *.log sistema1.log sistema2.log sistema3.log $ ls *.txt relatorio1.txt relatorio2.txt relatorio3.txt relatorio4.txt relatorio5.txt $ echo relatorio[12].txt relatorio1.txt relatorio2.txt
a lista expandida. Experimente também echo *, echo relatorio?.txt e echo *.{txt,md} pra ver como cada coringa se comporta.
Por que o echo mostra a lista se eu não digitei os nomes?
Porque o echo nunca viu o coringa. O shell substituiu *.log pela lista de arquivos correspondentes antes de chamar o echo — que apenas imprimiu o que recebeu. É exatamente isso que acontece com rm, cp e todos os outros. Por isso testar com echo é seguro e confiável.
por que testar um coringa com echo ou ls antes de usá-lo num rm é uma boa prática? Quem expande o coringa: o shell ou o comando?
0 / 40 caracteres
Passo 3 de 6
Manipulando em lote
mv *.log logs/ && ls logs/O que é
Move todos os arquivos .log de uma vez para o subdiretório logs/. O mesmo mv também renomeia, quando o destino é um nome de arquivo.
Por que importa
É a resposta da pergunta do slide: organizar dezenas ou centenas de arquivos num comando, não num por um.
$ mv *.log logs/ && ls logs/ sistema1.log sistema2.log sistema3.log $ cp -r logs/ logs_backup/ $ ls logs logs_backup notas.md relatorio1.txt ...
os três .log agora dentro de logs/ e uma cópia completa em logs_backup/. Sem o -r no cp, copiar um diretório dá erro — teste e veja a mensagem.
Passo 4 de 6
Procurar arquivos e procurar conteúdo
find ~/lab12 -name "*.log" e grep -rn "ERRO" ~/lab12O que é
find percorre a árvore de diretórios procurando pelo nome. grep -rn procura dentro dos arquivos, mostrando arquivo e número da linha.
Por que importa
"Onde está esse arquivo?" e "onde aparece essa mensagem de erro?" são duas perguntas distintas, com ferramentas distintas.
$ echo "[ERRO] falha ao conectar" > logs/sistema1.log $ find ~/lab12 -name "*.log" /home/aluno/lab12/logs/sistema1.log /home/aluno/lab12/logs/sistema2.log /home/aluno/lab12/logs/sistema3.log /home/aluno/lab12/logs_backup/sistema1.log /home/aluno/lab12/logs_backup/sistema2.log /home/aluno/lab12/logs_backup/sistema3.log $ grep -rn "ERRO" ~/lab12 /home/aluno/lab12/logs/sistema1.log:1:[ERRO] falha ao conectar
o find lista caminhos de arquivos (a ordem pode variar); o grep -rn mostra arquivo:linha:conteúdo. Repare que o find encontrou também as cópias em logs_backup/, mas o grep só achou a mensagem onde ela realmente foi escrita — a cópia foi feita antes do echo. E note as aspas em "*.log": sem elas, o shell expandiria o coringa antes, e o find receberia nomes em vez do padrão.
Meu grep não encontrou nada
Confirme que você rodou o echo "[ERRO] ..." > logs/sistema1.log antes — os arquivos criados com touch no passo 1 estão vazios. O grep diferencia maiúsculas de minúsculas por padrão; use grep -rni para ignorar essa diferença.
Passo 5 de 6
Substituir ou acrescentar: a diferença que importa
> versus >>O que é
> substitui todo o conteúdo do arquivo. >> acrescenta ao final, preservando o que já existia.
Por que importa
Todo script que grava log usa >>. Usar > por engano descarta silenciosamente todo o histórico anterior.
$ echo "primeira linha" > relatorio.txt $ echo "segunda linha" >> relatorio.txt $ cat relatorio.txt primeira linha segunda linha $ echo "apaguei tudo" > relatorio.txt $ cat relatorio.txt apaguei tudo
as duas primeiras linhas convivendo, e depois desaparecendo quando o > é usado. Rode você mesmo e veja o conteúdo sumir — é uma lição que se aprende melhor vendo.
qual a diferença prática entre > e >>? Descreva uma situação real em que usar o errado causaria um problema sério.
0 / 40 caracteres
Passo 6 de 6
Os mesmos comandos, do lado de dentro
docker exec no Encontro 5. Agora dá pra usar de forma interativa — abrindo um shell dentro do container e trabalhando lá.docker run -d --name shelldemo alpine sleep 600 depois docker exec -it shelldemo shO que é
-it significa interativo + terminal: em vez de rodar um comando e sair, você fica dentro do container, com um shell próprio.
Por que importa
É exatamente assim que se diagnostica um container quebrado em produção — entrando nele e usando os comandos básicos.
$ docker exec -it shelldemo sh $ pwd / $ ls / bin dev etc home proc root tmp usr var $ mkdir -p /teste && touch /teste/arq{1..3}.txt && ls /teste arq1.txt arq2.txt arq3.txt $ exit
o prompt muda para / # — você está dentro do container. Os coringas funcionam igual. Note que a árvore de arquivos é outra: você não vê seu ~/lab12 ali, porque é um sistema de arquivos isolado. Digite exit para voltar.
Por que "sh" e não "bash"?
A imagem alpine é mínima e não inclui o bash — só o sh, mais básico. É um bom lembrete de por que dominar os comandos essenciais importa: em imagens enxutas você não tem as ferramentas confortáveis à disposição, e não dá pra instalar nada no meio de um incidente.
Limpeza: ao sair, rode docker stop shelldemo && docker rm shelldemo.
livre: o que você notou ao usar os comandos dentro do container em vez do host? Ou uma dúvida que sobrou de hoje
0 / 40 caracteres
Exemplo de observação forte × fraca
Observação fraca
"É melhor testar com echo antes de apagar."
Observação forte
"Quem expande o coringa é o shell, não o comando — quando rodei echo *.log, o echo recebeu a lista já pronta e nunca viu o asterisco. Como rm funciona exatamente do mesmo jeito, testar o padrão com echo ou ls antes mostra precisamente o que seria apagado. Sem lixeira no shell, essa checagem é a única defesa contra apagar um arquivo que casava com o padrão sem eu perceber."
Checklist final
- Criei a estrutura de teste em
~/lab12 - Testei coringas com
echoantes de usá-los - Movi e copiei arquivos em lote com coringa
- Usei
findpor nome egrep -rnpor conteúdo - Comprovei a diferença entre
>e>> - Entrei num container com
docker exec -ite usei os comandos lá dentro - Limpei o container de teste
- Preenchi as 3 observações acima (vou colar no quiz semanal)