Perguntas e Respostas para Entrevista de Shell

ShellBeginner
Pratique Agora

Introdução

Bem-vindo a este guia abrangente sobre Perguntas e Respostas para Entrevistas de Shell! Quer você esteja se preparando para uma entrevista, procurando aprimorar suas habilidades existentes ou simplesmente curioso sobre a amplitude do conhecimento em shell, este documento foi projetado para ser seu recurso definitivo. Cobrimos tudo, desde conceitos fundamentais e scripting avançado até resolução de problemas baseada em cenários e desafios específicos de função, garantindo que você esteja bem equipado para qualquer discussão técnica. Mergulhe para explorar tarefas práticas, técnicas de solução de problemas, melhores práticas e considerações essenciais de segurança, capacitando você a demonstrar com confiança sua experiência em scripting de shell e proficiência em linha de comando.

SHELL

Conceitos e Comandos Fundamentais de Shell

Resposta:

Um hard link aponta diretamente para o inode de um arquivo, o que significa que é uma entrada de diretório adicional para os mesmos dados do arquivo. Um soft link (symlink) é um arquivo especial que contém um caminho para outro arquivo ou diretório. Hard links não podem abranger diferentes sistemas de arquivos e não podem linkar para diretórios, enquanto soft links podem.


Explique o propósito da variável de ambiente PATH.

Resposta:

A variável de ambiente PATH é uma lista de diretórios separados por dois pontos que o shell procura por comandos executáveis quando um comando é inserido sem seu caminho completo. Isso permite que os usuários executem comandos como ls ou grep sem especificar /bin/ls ou /usr/bin/grep.


Como você redireciona a saída padrão e o erro padrão para arquivos separados?

Resposta:

Você pode redirecionar a saída padrão (1) e o erro padrão (2) para arquivos separados usando command > output.txt 2> error.txt. Isso envia a saída bem-sucedida para output.txt e as mensagens de erro para error.txt.


Qual é a diferença entre os comandos exec e source (ou . )?

Resposta:

exec substitui o processo do shell atual pelo comando especificado, o que significa que o shell original é encerrado. source (ou .) executa um script no ambiente do shell atual, o que significa que quaisquer variáveis ou funções definidas no script se tornam parte do ambiente do shell atual.


Descreva a função do comando grep e forneça um exemplo básico.

Resposta:

grep (Global Regular Expression Print) é usado para procurar padrões em arquivos de texto. Ele imprime linhas que correspondem a uma expressão regular dada. Por exemplo, grep 'error' logfile.txt exibirá todas as linhas que contêm a palavra 'error' em logfile.txt.


Como você encontra todos os arquivos maiores que 10MB no diretório atual e seus subdiretórios?

Resposta:

Você pode usar o comando find: find . -type f -size +10M. Este comando procura no diretório atual (.) por arquivos (-type f) que são maiores que (+) 10 megabytes (10M).


Explique o conceito de 'piping' no shell.

Resposta:

Piping (|) é um mecanismo para conectar a saída padrão de um comando à entrada padrão de outro comando. Isso permite encadear vários comandos para realizar operações complexas, onde a saída de um comando se torna a entrada para o próximo.


Qual é a importância do caractere ~ (tilde) no shell?

Resposta:

O caractere ~ (tilde) é uma notação abreviada que se expande para o diretório home do usuário atual. Por exemplo, cd ~/documents mudará o diretório para a pasta documents dentro do diretório home do usuário.


Como você visualiza o conteúdo de um arquivo gzipped compactado sem descompactá-lo?

Resposta:

Você pode usar o comando zcat. Por exemplo, zcat file.gz exibirá o conteúdo descomprimido de file.gz para a saída padrão sem criar um arquivo descompactado no disco.


Qual é o propósito do comando chmod?

Resposta:

chmod (change mode) é usado para alterar as permissões de arquivos e diretórios. Ele controla quem pode ler, escrever ou executar um arquivo. As permissões podem ser definidas usando modos simbólicos (por exemplo, u+x) ou notação octal (por exemplo, 755).


Scripting e Programação Avançada

Explique a diferença entre 'source' e executar um script diretamente (por exemplo, './script.sh').

Resposta:

Fazer o sourcing de um script (source script.sh ou . script.sh) o executa no ambiente do shell atual, o que significa que quaisquer variáveis ou funções definidas se tornam parte do shell atual. Executá-lo diretamente (./script.sh) executa o script em um novo subshell, de modo que as alterações no ambiente não são propagadas de volta para o shell pai.


Como você lida com erros e códigos de saída em um script de shell?

Resposta:

Erros são tipicamente tratados verificando o status de saída dos comandos usando $?. Um status de saída diferente de zero indica um erro. Você pode usar set -e para sair imediatamente se um comando falhar, ou trap para executar um comando na saída ou em sinais específicos.


Descreva o propósito de 'set -euxo pipefail' no início de um script.

Resposta:

set -e sai imediatamente se um comando sair com um status diferente de zero. set -u trata variáveis não definidas como erros. set -x imprime comandos e seus argumentos conforme são executados. set -o pipefail faz com que um pipeline retorne o status de saída do último comando que retornou um status diferente de zero, em vez de apenas o último comando no pipe.


Como você pode passar argumentos para um script de shell e acessá-los?

Resposta:

Os argumentos são passados diretamente após o nome do script (por exemplo, ./script.sh arg1 arg2). Dentro do script, eles são acessados usando parâmetros posicionais: $1 para o primeiro argumento, $2 para o segundo, e assim por diante. $# fornece o número total de argumentos, e $@ se expande para todos os argumentos como palavras separadas.


Explique o conceito de 'here documents' e forneça um exemplo simples.

Resposta:

Um 'here document' permite que você alimente várias linhas de entrada para um comando como se elas tivessem sido digitadas no teclado, sem criar um arquivo temporário. Ele é denotado por << DELIMITER. Exemplo: cat << EOF Hello World EOF.


O que é um comando 'trap' e quando você o usaria?

Resposta:

O comando trap permite que você execute um comando quando o shell recebe um sinal (por exemplo, SIGINT para Ctrl+C, SIGTERM para terminação) ou quando o shell sai. Ele é comumente usado para operações de limpeza, como remover arquivos temporários, garantindo que os recursos sejam liberados mesmo que o script seja interrompido.


Como você realiza operações aritméticas em Bash?

Resposta:

Operações aritméticas em Bash são tipicamente realizadas usando ((...)) ou $[...]. Por exemplo, result=$((5 + 3)) ou result=$[5 + 3]. O comando expr também pode ser usado, mas é mais antigo e menos eficiente para aritmética inteira simples.


Descreva como depurar um script de shell.

Resposta:

A depuração pode ser feita adicionando set -x no início do script ou executando bash -x script.sh. Isso imprime cada comando antes de ser executado. Você também pode inserir instruções echo para imprimir valores de variáveis em diferentes estágios de execução.


Qual é a diferença entre [[ e [ para expressões condicionais?

Resposta:

[[ é uma palavra-chave do Bash que oferece recursos mais avançados do que o [ compatível com POSIX (que é um comando externo). [[ suporta correspondência de padrões (=~), operadores lógicos (&&, ||) e evita divisão de palavras e expansão de nomes de caminho, tornando-o mais seguro e poderoso para testes de strings e arquivos.


Como você escreveria uma função em Bash e a chamaria?

Resposta:

Funções são definidas usando function_name() { commands; } ou function function_name { commands; }. Elas são chamadas simplesmente digitando seus nomes. Argumentos são passados para funções assim como para scripts, usando parâmetros posicionais ($1, $2, etc.) dentro do escopo da função. Exemplo: my_func() { echo $1; }; my_func 'hello'.


Resolução de Problemas Baseada em Cenários

Você precisa encontrar todos os arquivos maiores que 10MB no diretório atual e seus subdiretórios, depois listar seus caminhos e tamanhos em um formato legível por humanos. Como você faria isso?

Resposta:

Use find . -type f -size +10M -exec du -h {} \;. find localiza arquivos, -type f especifica arquivos, -size +10M filtra por tamanho, e -exec du -h {} \; executa du -h para cada arquivo encontrado.


Um arquivo de log /var/log/app.log está crescendo rapidamente. Você precisa extrair todas as linhas que contêm a palavra 'ERROR' das últimas 24 horas e salvá-las em um novo arquivo errors_today.log. Assuma que as entradas de log começam com um timestamp.

Resposta:

Primeiro, determine o timestamp de 24 horas atrás. Em seguida, use grep com awk ou sed para filtrar. Exemplo: grep 'ERROR' /var/log/app.log | awk '$1 >= "$(date -d '24 hours ago' +'%Y-%m-%d')"' > errors_today.log. Uma solução mais robusta pode envolver logrotate ou journalctl se disponíveis.


Você tem um arquivo CSV data.csv com as colunas Name,Age,City. Você precisa ordená-lo por Age em ordem decrescente e depois por Name em ordem crescente, exibindo apenas Name e City.

Resposta:

Use sort com cut e awk. (head -n 1 data.csv; tail -n +2 data.csv | sort -t',' -k2nr -k1n) para ordenar. Em seguida, cut -d',' -f1,3 ou awk -F',' '{print $1 "," $3}' para selecionar colunas. Combinando: (head -n 1 data.csv; tail -n +2 data.csv | sort -t',' -k2nr -k1) | awk -F',' '{print $1 "," $3}'.


Um script myscript.sh está rodando em segundo plano, mas você suspeita que ele travou. Como você verificaria seu status e, se ele estiver sem resposta, como o terminaria graciosamente, e depois forçadamente, se necessário?

Resposta:

Verifique o status com ps aux | grep myscript.sh. Para terminar graciosamente, use kill <PID>. Se ele não responder, use kill -9 <PID> para uma terminação forçada. Sempre tente a terminação graciosa primeiro para permitir a limpeza.


Você precisa criar um backup do diretório /etc, compactá-lo usando gzip e armazená-lo em /tmp/etc_backup_YYYYMMDD.tar.gz. Como você automatizaria isso?

Resposta:

Use tar com gzip. tar -czf /tmp/etc_backup_$(date +%Y%m%d).tar.gz /etc. Este comando cria um arquivo tar compactado com gzip (-c create, -z gzip, -f filename) com um nome com data.


Você está solucionando um problema de rede. Como você verificaria se uma porta específica (por exemplo, 8080) está aberta e escutando em sua máquina local, e qual processo a está usando?

Resposta:

Use netstat -tulnp | grep :8080 ou lsof -i :8080. netstat mostra conexões de rede, -t TCP, -u UDP, -l listening, -n numeric, -p process ID. lsof lista arquivos abertos, incluindo sockets de rede.


Você precisa baixar um arquivo de uma URL (http://example.com/file.zip) e salvá-lo como downloaded_file.zip no diretório atual. Como você faria isso usando uma ferramenta de linha de comando?

Resposta:

Use wget ou curl. Com wget: wget -O downloaded_file.zip http://example.com/file.zip. Com curl: curl -o downloaded_file.zip http://example.com/file.zip. Ambas as ferramentas são comuns para downloads HTTP/HTTPS.


Você tem um diretório com muitos arquivos e precisa renomear todos os arquivos que terminam com .txt para que terminem com .log em vez disso. Como você realizaria isso?

Resposta:

Use um loop for com mv. for f in *.txt; do mv "$f" "${f%.txt}.log"; done. A sintaxe "${f%.txt}.log" remove o sufixo .txt e anexa .log.


Você precisa encontrar os 5 maiores arquivos no diretório /var, excluindo subdiretórios como /var/cache e /var/log.

Resposta:

Use du e sort. du -ah --exclude=/var/cache --exclude=/var/log /var | sort -rh | head -n 5. du -ah lista tamanhos em formato legível por humanos, sort -rh ordena numericamente em reverso, e head -n 5 obtém os 5 primeiros.


Um script precisa ser executado todos os dias às 3 da manhã. Como você agendaria essa tarefa?

Resposta:

Use cron. Adicione uma entrada ao crontab: 0 3 * * * /path/to/your/script.sh. Isso significa no minuto 0, hora 3, todos os dias do mês, todos os meses e todos os dias da semana, execute o script.


Perguntas Específicas por Função (Desenvolvedor, Administrador, DevOps)

Desenvolvedor: Como você depuraria um script de shell que falha intermitentemente sem mensagens de erro claras?

Resposta:

Eu começaria adicionando set -x no início do script para habilitar o rastreamento, que mostra os comandos e seus argumentos conforme são executados. Para uma depuração mais direcionada, eu usaria instruções echo para imprimir valores de variáveis em pontos críticos. Redirecionar o stderr para um arquivo (2> error.log) também pode ajudar a capturar erros esquivos.


Desenvolvedor: Explique a diferença entre $() e `` (crases) para substituição de comando.

Resposta:

Tanto $() quanto ``(crases) realizam substituição de comando, executando um comando e substituindo-o por sua saída. No entanto, $() é geralmente preferido porque permite aninhamento sem escape complexo e é mais legível. As crases exigem o escape de crases aninhadas, tornando-as mais difíceis de gerenciar.


Desenvolvedor: Escreva um script de shell para encontrar todos os arquivos maiores que 10MB em um determinado diretório e seus subdiretórios, e depois listá-los por tamanho em ordem decrescente.

Resposta:

find /path/to/dir -type f -size +10M -print0 | xargs -0 du -h | sort -rh

Este comando usa find para localizar arquivos, xargs para passá-los para du para relatar o tamanho, e sort -rh para ordenar por tamanho legível por humanos em ordem reversa.


Administrador: Como você monitoraria o uso do espaço em disco em um servidor Linux e configuraria um alerta se ele excedesse 90%?

Resposta:

Eu usaria df -h para verificar o espaço em disco. Para automatizar alertas, eu escreveria um script que analisasse a saída do df, verificasse a porcentagem para partições críticas e, em seguida, usaria mail ou uma API de mensagens (como um webhook do Slack) para enviar um alerta se o limite fosse ultrapassado. Este script seria agendado via cron.


Administrador: Descreva os passos para automatizar um backup diário de um diretório específico para um servidor remoto usando SSH.

Resposta:

Primeiro, garanta que a autenticação baseada em chave SSH esteja configurada entre os servidores de origem e destino para evitar prompts de senha. Em seguida, use rsync -avz /source/dir/ user@remote:/destination/dir/ dentro de um script de shell. Agende este script para ser executado diariamente usando um job cron, garantindo o registro adequado e o tratamento de erros.


Administrador: Qual é o propósito do arquivo /etc/fstab e quais são os problemas comuns que você pode encontrar com ele?

Resposta:

/etc/fstab define sistemas de arquivos estáticos a serem montados no momento da inicialização. Problemas comuns incluem caminhos de dispositivo incorretos, tipos de sistema de arquivos errados ou opções de montagem inválidas, que podem levar a falhas de inicialização ou partições não montadas. O uso de nofail pode prevenir problemas de inicialização para montagens não críticas.


DevOps: Como você garante a idempotência em seus scripts de shell para provisionamento de infraestrutura?

Resposta:

Idempotência significa que executar um script várias vezes produz o mesmo resultado que executá-lo uma vez. Eu consigo isso verificando a existência de recursos antes de criá-los (por exemplo, if [ ! -f /path/to/file ]; then ... fi). Para instalações de pacotes, eu uso gerenciadores de pacotes que lidam com idempotência (por exemplo, apt install -y package só instala se não estiver presente). Ferramentas de gerenciamento de configuração como Ansible ou Puppet fornecem idempotência inerentemente.


DevOps: Explique como você usaria um script de shell em um pipeline CI/CD para implantar um aplicativo.

Resposta:

Em um pipeline CI/CD, um script de shell normalmente lidaria com tarefas como buscar artefatos, parar serviços existentes, implantar novo código (por exemplo, copiar arquivos, extrair arquivos compactados), executar migrações de banco de dados e iniciar serviços. Ele incluiria tratamento de erros e registro, muitas vezes interagindo com comandos systemctl ou docker. Variáveis de ambiente seriam usadas para configuração.


DevOps: Quais são algumas melhores práticas para escrever scripts de shell robustos e de fácil manutenção em um ambiente de equipe?

Resposta:

Melhores práticas incluem usar set -euo pipefail para tratamento de erros, adicionar comentários, usar funções para modularizar o código, convenções de nomenclatura consistentes, validar entradas e fornecer instruções de uso claras. Controle de versão, ferramentas de linting (como ShellCheck) e testes completos também são cruciais para colaboração em equipe e manutenibilidade.


DevOps: Como você lidaria com segredos (por exemplo, chaves de API, senhas) em scripts de shell em um contexto CI/CD?

Resposta:

Segredos nunca devem ser codificados diretamente. Em CI/CD, eu usaria variáveis de ambiente fornecidas pela plataforma CI/CD (por exemplo, credenciais Jenkins, variáveis do GitLab CI/CD). Para cenários mais sensíveis ou complexos, eu me integraria a um sistema de gerenciamento de segredos como HashiCorp Vault ou AWS Secrets Manager, recuperando segredos em tempo de execução em vez de armazená-los em scripts ou repositórios.


Scripting Prático e Tarefas Mãos à Obra

Escreva um script de shell que receba um caminho de diretório como argumento e conte o número de arquivos regulares e subdiretórios dentro dele. Lide com casos em que o diretório não existe.

Resposta:

#!/bin/bash
DIR="$1"
if [ ! -d "$DIR" ]; then
  echo "Error: Directory '$DIR' not found."
  exit 1
fi
files=$(find "$DIR" -maxdepth 1 -type f | wc -l)
dirs=$(find "$DIR" -maxdepth 1 -type d | wc -l)
## Subtract 1 from dirs for the directory itself
echo "Files: $files, Directories: $((dirs - 1))"

Como você encontraria todos os arquivos maiores que 10MB no diretório atual e seus subdiretórios, e depois os listaria ordenados por tamanho?

Resposta:

Use find . -type f -size +10M -print0 | xargs -0 du -h | sort -rh. find localiza arquivos, -print0 e xargs -0 lidam com caracteres especiais, du -h obtém tamanhos legíveis por humanos, e sort -rh ordena por tamanho em ordem reversa legível por humanos.


Escreva uma linha de comando para substituir todas as ocorrências de 'foo' por 'bar' em todos os arquivos .txt no diretório atual.

Resposta:

find . -maxdepth 1 -type f -name "*.txt" -exec sed -i 's/foo/bar/g' {} \;

Isso usa find para localizar arquivos .txt e sed -i para substituição no local. Alternativamente, grep -lR foo *.txt | xargs sed -i 's/foo/bar/g'.


Explique a diferença entre $$ e $! em scripting de shell.

Resposta:

$$ se expande para o ID do processo (PID) do shell atual. $! se expande para o PID do comando em segundo plano (assíncrono) executado mais recentemente. Eles são úteis para criar arquivos temporários únicos ou gerenciar processos em segundo plano.


Como você analisa argumentos de linha de comando em um script de shell, especificamente argumentos nomeados como --file <path> ou -v?

Resposta:

Use getopts para opções curtas (-v) ou um loop while getopts. Para opções longas (--file), um loop while true; do case "$1" in ... esac; shift; done com instruções case é comum, frequentemente combinado com shift para consumir argumentos.


Escreva um script que monitore um arquivo de log (/var/log/syslog por exemplo) e imprima novas linhas à medida que são adicionadas, semelhante a tail -f.

Resposta:

#!/bin/bash
tail -f /var/log/syslog

Isso utiliza diretamente o comando tail -f, que é projetado para essa finalidade. Para uma abordagem mais manual, pode-se usar inotifywait ou um loop com wc -l e sed.


Como você garantiria que um script de shell saísse imediatamente se qualquer comando falhasse?

Resposta:

Adicione set -e no início do script. Esta opção faz com que o shell saia imediatamente se um comando retornar um status diferente de zero. É crucial para a execução robusta de scripts.


Você tem um arquivo CSV data.csv com as colunas Name,Age,City. Como você extrairia apenas as colunas Name e City usando ferramentas de shell padrão?

Resposta:

cut -d',' -f1,3 data.csv

Isso usa cut com um delimitador de vírgula (-d',') para selecionar o primeiro e o terceiro campos (-f1,3). Alternativamente, awk -F',' '{print $1 "," $3}' data.csv pode alcançar o mesmo.


Escreva uma função em um script de shell que receba dois números como argumentos e retorne sua soma.

Resposta:

#!/bin/bash
sum_numbers() {
  echo $(($1 + $2))
}
result=$(sum_numbers 10 5)
echo "Sum: $result"

Funções são definidas com nome_da_funcao() { ... }. A expansão aritmética $((...)) é usada para cálculos. O resultado é tipicamente exibido e capturado por substituição de comando.


Como você agenda um script para ser executado todos os dias às 3 da manhã?

Resposta:

Use cron. Adicione uma entrada ao arquivo crontab (crontab -e) como 0 3 * * * /path/to/your_script.sh. Os campos representam minuto, hora, dia do mês, mês e dia da semana, respectivamente.


Solução de Problemas e Depuração de Scripts de Shell

Melhores Práticas e Otimização de Desempenho de Scripts de Shell

Como otimizar um script de shell para desempenho ao lidar com arquivos grandes ou muitas iterações?

Resposta:

Evite forks desnecessários (por exemplo, usar grep dentro de um loop). Use recursos nativos do shell sempre que possível (por exemplo, expansão de parâmetros em vez de sed). Processe dados em blocos ou use awk para processamento eficiente linha a linha.


Explique a diferença entre $(command) e `command` para substituição de comando e qual é preferível como melhor prática.

Resposta:

$(command) é a sintaxe moderna e preferida. Ela lida com aninhamento com mais facilidade e evita problemas com barras invertidas e aspas que podem ocorrer com crases (`command`). $(command) é geralmente mais legível e robusto.


Qual é o propósito de set -e e set -u em um script de shell, e por que eles são considerados boas práticas?

Resposta:

set -e (errexit) faz com que o script saia imediatamente se um comando retornar um status diferente de zero. set -u (nounset) trata variáveis não definidas como um erro e sai. Ambos melhoram a robustez do script, capturando erros precocemente e prevenindo comportamentos inesperados.


Como você pode prevenir o 'globbing' ou a expansão de nomes de caminho em um script de shell?

Resposta:

Para prevenir o globbing, envolva a string entre aspas duplas. Por exemplo, ls "*.txt" tratará *.txt como uma string literal, enquanto ls *.txt se expandirá para todos os arquivos .txt no diretório atual.


Quando você deve usar [[ ... ]] em vez de [ ... ] para expressões condicionais em Bash?

Resposta:

[[ ... ]] é uma palavra-chave específica do Bash que oferece mais recursos do que o comando [ ... ] compatível com POSIX. Ele suporta correspondência de padrões (=~), operadores lógicos (&&, ||) e evita a divisão de palavras e a expansão de nomes de caminho, tornando-o mais seguro e poderoso.


Descreva um cenário onde usar xargs seria mais eficiente do que um loop for.

Resposta:

xargs é mais eficiente ao processar uma grande lista de itens como argumentos para um comando. Ele constrói linhas de comando com múltiplos argumentos, reduzindo o número de vezes que o comando alvo é invocado, ao contrário de um loop for que normalmente chama o comando uma vez por item.


Qual é o significado de redirecionar stderr para /dev/null (por exemplo, 2>/dev/null)?

Resposta:

Redirecionar stderr para /dev/null descarta mensagens de erro, impedindo que elas sejam exibidas no console ou poluam a saída. Isso é útil para suprimir erros esperados ou quando você se importa apenas com stdout.


Como você pode tornar um script de shell mais portátil entre diferentes sistemas Unix-like?

Resposta:

Use comandos e recursos compatíveis com POSIX sempre que possível. Evite extensões específicas do Bash como [[ ... ]] ou substituição de processo se a portabilidade estrita for necessária. Especifique o interpretador explicitamente usando um shebang como #!/bin/sh.


Por que geralmente é uma má prática analisar a saída de ls em scripts de shell?

Resposta:

Analisar a saída de ls é problemático porque nomes de arquivos podem conter espaços, novas linhas ou caracteres especiais, o que pode quebrar a lógica do script ao ser processado por ferramentas como awk ou loops for. Use find -print0 | xargs -0 para manipulação segura de nomes de arquivos.


Qual é o propósito de trap em scripting de shell e forneça um exemplo simples.

Resposta:

trap permite que você execute comandos quando o shell recebe um sinal (por exemplo, EXIT, INT, TERM). É crucial para operações de limpeza. Exemplo: trap 'rm -f /tmp/mytempfile' EXIT garante que um arquivo temporário seja removido quando o script sair.


Controle de Versão e Colaboração com Shell

Como você usa o Git tipicamente a partir da linha de comando para tarefas de desenvolvimento diárias?

Resposta:

Eu uso principalmente git status, git add, git commit -m "mensagem", git pull e git push. Para ramificação (branching), uso git checkout -b nome-do-branch e git merge ou git rebase.


Explique a diferença entre git pull e git fetch.

Resposta:

git fetch baixa novos dados de um repositório remoto, mas não os integra aos seus arquivos de trabalho. git pull é essencialmente git fetch seguido por git merge (ou git rebase, dependendo da configuração), integrando as alterações ao seu branch atual.


Como você reverteria um commit específico que já foi enviado para um repositório remoto?

Resposta:

Eu usaria git revert <hash-do-commit>. Isso cria um novo commit que desfaz as alterações do commit especificado, preservando o histórico do projeto. É mais seguro do que git reset --hard para branches compartilhados.


Descreva um cenário onde você usaria git rebase em vez de git merge.

Resposta:

Eu usaria git rebase para manter um histórico de projeto limpo e linear, especialmente em branches de recursos antes de mesclar (merge) no main. Ele reaplica commits de um branch sobre outro, evitando commits de merge e tornando o histórico mais fácil de ler.


Como você resolve conflitos de merge usando a linha de comando?

Resposta:

Após um conflito de merge, git status mostra os arquivos em conflito. Eu edito manualmente esses arquivos para resolver os conflitos, depois uso git add <arquivo-em-conflito> para marcá-los como resolvidos. Finalmente, completo o merge com git commit.


O que é git stash e quando você o usaria?

Resposta:

git stash salva temporariamente alterações que não estão prontas para serem commitadas, permitindo que você mude de branch ou execute outras tarefas. É útil quando você precisa mudar de contexto rapidamente sem commitar trabalho incompleto.


Como você pode visualizar o histórico de commits de um arquivo específico?

Resposta:

Eu uso git log -- <caminho-do-arquivo>. Este comando mostra todos os commits que afetaram o arquivo especificado, incluindo o hash do commit, autor, data e mensagem do commit.


Você acidentalmente comitou informações sensíveis. Como você as remove do seu histórico Git?

Resposta:

Para commits recentes e não enviados, git reset HEAD~1 seguido de emendar o commit é uma opção. Para commits enviados ou histórico mais profundo, git filter-branch ou BFG Repo-Cleaner são usados para reescrever o histórico, mas isso é disruptivo e requer force-push.


Explique o propósito de um arquivo .gitignore.

Resposta:

Um arquivo .gitignore especifica arquivos intencionalmente não rastreados que o Git deve ignorar. Isso impede que arquivos temporários, artefatos de build ou arquivos de configuração sensíveis sejam acidentalmente commitados no repositório.


Como você cria e muda para um novo branch no Git?

Resposta:

Para criar e mudar para um novo branch, eu uso git checkout -b nome-do-novo-branch. Este comando é um atalho para git branch nome-do-novo-branch seguido por git checkout nome-do-novo-branch.


Considerações de Segurança em Scripts de Shell

Por que é perigoso executar scripts de shell baixados de fontes não confiáveis?

Resposta:

Scripts não confiáveis podem conter código malicioso que poderia excluir arquivos, instalar malware, roubar dados sensíveis ou criar backdoors. Eles são executados com as permissões do usuário que os executa, tornando-os um risco de segurança significativo.


Como você pode prevenir vulnerabilidades de injeção de comando em scripts de shell?

Resposta:

Sempre coloque variáveis que contêm entrada do usuário entre aspas, especialmente ao serem usadas em comandos. Use set -e e set -u para capturar erros e variáveis não definidas. Evite eval com entrada não confiável. Prefira comandos específicos em vez de gerais e valide a entrada rigorosamente.


Explique a importância da validação de entrada em scripts de shell para segurança.

Resposta:

A validação de entrada garante que os dados fornecidos a um script estejam em conformidade com os formatos e valores esperados, impedindo que entradas maliciosas sejam processadas. Isso mitiga riscos como injeção de comando, path traversal e buffer overflows, rejeitando caracteres inválidos ou perigosos.


Quais são os riscos de usar eval em scripts de shell e quando isso pode ser aceitável?

Resposta:

eval executa seus argumentos como comandos de shell, tornando-o altamente suscetível à injeção de comando se usado com entrada não confiável. Geralmente é aceitável apenas quando a entrada é totalmente controlada e confiável pelo próprio script, ou ao construir dinamicamente comandos simples e seguros.


Como você pode lidar com segurança com informações sensíveis como senhas ou chaves de API em scripts de shell?

Resposta:

Evite codificar dados sensíveis diretamente em scripts. Em vez disso, use variáveis de ambiente (com cautela), arquivos de configuração seguros com permissões restritas ou ferramentas dedicadas de gerenciamento de segredos como HashiCorp Vault ou AWS Secrets Manager. Nunca os armazene em controle de versão.


Por que é importante definir permissões de arquivo apropriadas para scripts de shell e seus arquivos de saída?

Resposta:

Permissões de arquivo incorretas podem permitir que usuários não autorizados leiam, modifiquem ou executem scripts ou suas saídas. Scripts geralmente devem ser executáveis apenas pelo seu proprietário, e arquivos de saída sensíveis devem ter permissões restritivas de leitura/escrita para evitar vazamento ou adulteração de dados.


Qual é o propósito de set -u (ou set -o nounset) em um script de shell para segurança?

Resposta:

set -u faz com que o script saia imediatamente se tentar usar uma variável não definida. Isso previne comportamentos inesperados ou vulnerabilidades de segurança que poderiam surgir de uma variável não inicializada sendo interpretada como uma string vazia ou um valor padrão, potencialmente levando à execução de comandos ou operações de arquivo não intencionais.


Descreva o conceito de 'privilégio mínimo' no contexto da execução de scripts de shell.

Resposta:

O princípio do privilégio mínimo dita que um script deve ser executado com as permissões mínimas necessárias para realizar sua função pretendida. Isso limita o dano potencial caso o script seja comprometido, pois ele não terá acesso elevado a sistemas ou dados de que não precisa.


Como a manipulação de PATH pode levar a vulnerabilidades de segurança em scripts de shell?

Resposta:

Se a variável de ambiente PATH não for cuidadosamente controlada, um usuário malicioso poderia injetar seu próprio diretório contendo um executável com nome semelhante (por exemplo, ls ou rm). Quando o script chamar esse comando, ele poderá executar a versão maliciosa em vez da legítima, levando a ações não intencionais.


Quais são algumas melhores práticas para escrever scripts de shell seguros?

Resposta:

Valide toda a entrada do usuário, coloque variáveis entre aspas, use set -euo pipefail, evite eval com dados não confiáveis, defina permissões de arquivo restritivas, use caminhos absolutos para comandos e siga o princípio do privilégio mínimo. Audite regularmente os scripts em busca de vulnerabilidades e mantenha-os atualizados.


Resumo

Uma preparação completa é fundamental para o sucesso no rigoroso processo de entrevista da Shell. Ao revisar diligentemente perguntas comuns, entender os valores da Shell e praticar suas respostas, você aumenta significativamente suas chances de demonstrar suas capacidades e adequação para a função. Este documento serve como um recurso valioso para guiar sua preparação, ajudando-o a antecipar possíveis questionamentos e formular respostas convincentes.

Lembre-se, a jornada não termina com a entrevista. A indústria de energia é dinâmica e o aprendizado contínuo é a chave para o crescimento profissional. Abrace todas as oportunidades para expandir seu conhecimento e habilidades, garantindo que você permaneça um ativo valioso em um cenário em constante evolução. Sua dedicação à preparação e ao aprendizado ao longo da vida, sem dúvida, abrirá caminho para uma carreira gratificante.