Com o tempo, a maioria dos aficionados do Linux acumula um baú de guerra cheio de truques duramente conquistados que podem ser extremamente úteis quando uma situação exige raciocínio rápido em seu terminal. Eu guardei muitos desses conhecimentos ao longo dos anos e sempre que tive a oportunidade de observar alguém excepcionalmente versado em Linux.
Hoje, você está emparelhando comigo no terminal. Estamos explorando as profundezas do sistema de arquivos Linux e ferramentas e truques de shell.
/proc
comigo Um dos diretórios mais úteis em um sistema Linux é /proc
. Na página de man
do proc
:
O sistema de arquivos proc é um pseudo-sistema de arquivos que fornece uma interface para as estruturas de dados do kernel.
Quando a página do man
diz "pseudo-filesystem", significa que se você espiar embaixo do seu disco, onde pode esperar encontrar bits representando um arquivo como faria para um arquivo de texto em /tmp/launch-codes.txt
, há nada em /proc
. Ele está presente e ativo em um sistema Linux em execução, mas totalmente ausente se você retirar o disco e inspecioná-lo. /proc
um painel de controle para o kernel em execução!
Se você der uma olhada em seu próprio /proc
agora, poderá encontrar muitos diretórios como o seguinte:
ls /proc
1 10 10021 10059 10144 ...hundreds more files...
Cada um desses números representa um ID de processo, ou PID
– sim, o mesmo PID
que identifica o processo para seu navegador ou programa de terminal. Na verdade, você pode interrogar muitas informações sobre o próprio processo. Por exemplo, você deve se lembrar que o processo 1
em um sistema Linux é tradicionalmente o processo init
de nível superior, que na maioria dos sistemas modernos é baseado em systemd. Vamos ver o comando que iniciou o PID 1
no meu sistema:
cat /proc/1/cmdline
/run/current-system/systemd/lib/systemd/systemd
cmdline
é um arquivo que nos informa o comando que iniciou o processo 1
- neste caso, o próprio systemd
.
Há um arquivo cmdline
em /proc
que é particularmente útil - /proc/cmdline
, que na verdade mostra os argumentos passados para o próprio kernel no momento da inicialização. O meu é muito prolixo, mas me diz o initrd
com o qual meu sistema inicializou, junto com quaisquer outros sinalizadores, que no meu caso é init
e loglevel
:
cat /proc/cmdline
initrd=\efi\nixos\hx5g5rmvq748m64r32yjmpjk3pmgqmr1-initrd-linux-5.17.11-initrd.efi init=/nix/store/9zvklk45yx41pak2hdxsxmmnq12n712k-nixos-system-diesel-22.05.20220604.d9794b0/init loglevel=4
Meu hostname NixOS é diesel
. Observe que não coloco petróleo no meu laptop.
/proc
também não é apenas somente leitura. Como diz sua página de manual, /proc
é uma interface para o kernel, que inclui a interação com o próprio kernel. O diretório /proc/sys
contém uma variedade de botões e mostradores, mas quero mostrar a você /proc/sys/vm
, que nos permite espiar a memória virtual do kernel. Quer se aventurar mais?
Considere o uso de memória atual da minha máquina.
free -h
total used free shared buff/cache available Mem: 31Gi 22Gi 3.0Gi 4.4Gi 5.6Gi 3.6Gi Swap: 31Gi 130Mi 31Gi
Nada muito incomum aqui – mas e se eu quisesse liberar minha memória agressivamente? Na maioria das vezes, o kernel sabe melhor quando se trata de usar memória para cache, mas há algumas situações em que você pode querer limpar qualquer memória que seja segura para limpar - não queremos interromper nenhum processo em execução, apenas recuperar memória, se possível.
Acontece que há um arquivo para isso. Canalizamos um comando echo
em sudo tee
porque /proc/sys/vm
geralmente é protegido contra gravação e somente o root
pode gravar no arquivo em que estamos interessados.
echo 1 | sudo tee -a /proc/sys/vm/drop_caches
O que esse comando faz é efetivamente sinalizar para o kernel, "por favor, elimine todos os caches na memória que você pode perder sem interromper nenhum processo em execução no meu sistema". Na minha máquina, isso abre cerca de 500M de memória:
total used free shared buff/cache available Mem: 31Gi 22Gi 3.5Gi 4.4Gi 5.1Gi 3.6Gi Swap: 31Gi 130Mi 31Gi
Legal! Existem todos os tipos de objetos úteis semelhantes a arquivos em /proc
que podem fazer coisas interessantes como esta. Sinta-se à vontade para abrir man proc
se quiser saber mais.
/dev
como um curl
pré-histórico Um dispositivo de caractere como /dev/sda
representa um disco anexado, mas há outro uso para o caminho /dev
: uma maneira pouco conhecida de enviar solicitações de rede.
O caminho /dev/tcp
não é realmente um dispositivo semelhante a um arquivo exposto pelo kernel do Linux, mas sim um recurso do shell escolhido como bash
. Os shells podem interceptar operações neste caminho para abrir conexões de soquete de baixo nível para terminais remotos, como servidores da Web que escutam na porta 80
.
Para começar, abra um novo descritor de arquivo conectado a um caminho de arquivo em /dev/tcp
que indique o terminal e a porta desejados. Assim como os números do descritor de arquivo 0, 1 e 2 representam stdin
, stdout
e stderr
, respectivamente, você pode pensar nesse novo descritor de arquivo 3 como representando um canal para um terminal de rede remoto. Assumiremos o uso de bash
daqui em diante.
exec 3<>/dev/tcp/httpbin.org/80
Em seguida, envie a forma de texto simples de uma solicitação HTTP simples para o descritor de arquivo aberto. Essa solicitação GET
para /status/200
também requer que o cabeçalho Host
seja definido para ser tratado adequadamente pela maioria dos proxies reversos. Duas novas linhas sinalizam o término da solicitação:
echo -e "GET /status/200 HTTP/1.1\r\nHost: httpbin.org\r\n\r\n" >&3
Por fim, uma simples operação de leitura recupera a resposta HTTP:
cat <&3
Você deve ver uma resposta semelhante à abaixo:
HTTP/1.1 200 OK Date: Fri, 10 Jun 2022 21:39:43 GMT Content-Type: text/html; charset=utf-8 Content-Length: 0 Connection: keep-alive Server: gunicorn/19.9.0 Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true
Parabéns! Você acabou de enviar uma solicitação HTTP usando nada além de seu shell.
/sys
Há mais um diretório de nível raiz para explorar depois de mergulhar em /proc
e /dev
: o enigmático /sys
.
Como /proc
e /dev
, /sys
é outra interface semelhante a arquivo para mecanismos de baixo nível que ficam muito próximos do sistema operacional. Ao contrário /proc
- que é relativamente focado no processo - e /dev
- que modela dispositivos de bloco e mais - /sys
é uma interface útil para muitas abstrações que o kernel modela.
Por exemplo, pegue o diretório /sys/class/net
. Dentro desse diretório, você encontrará uma lista de links que representam as interfaces de rede em seu host. Veja como é o meu:
ls /sys/class/net
enp0s20f0u6u4u1 lo tailscale0 wlan0
Como você pode ver, as conexões de rede ativas que meu sistema está gerenciando incluem uma interface com fio (a interface que começa com en
), a interface lo
loopback, uma interface Tailscale e minha interface sem fio wlan0
. Listar o conteúdo de um desses diretórios revela uma longa lista de arquivos, mas vamos examinar mais de perto dois arquivos em particular para minha interface de rede com fio:
cat /sys/class/net/enp0s20f0u6u4u1/statistics/rx_bytes cat /sys/class/net/enp0s20f0u6u4u1/statistics/tx_bytes
11281235262 274308842
Cada um desses arquivos representa o número de bytes recebidos e bytes transmitidos, respectivamente. Confira como os números mudam se eu usar o mesmo comando alguns segundos depois:
cat /sys/class/net/enp0s20f0u6u4u1/statistics/rx_bytes cat /sys/class/net/enp0s20f0u6u4u1/statistics/tx_bytes
11289633209 274760138
Números maiores! Aparentemente, estou aproveitando ao máximo minha largura de banda. Como isso é útil?
Você já se perguntou como os widgets de uso da rede são escritos? Bem, que tal fazer o seu?
Confira este pequeno script bash
que usa os arquivos mencionados no diretório de statistics
para derivar uma taxa de atividade de rede.
interval=1 interface=$1 rx_bytes=$(cat /sys/class/net/$interface/statistics/rx_bytes) tx_bytes=$(cat /sys/class/net/$interface/statistics/tx_bytes) rx_bytes_rate=0 tx_bytes_rate=0 function fmt() { numfmt --to=iec-i --suffix=B $1 } while true do echo -en " $(fmt $tx_bytes_rate)/s ⬆ $(fmt $rx_bytes_rate)/s ⬇\t\r" sleep $interval old_rx_bytes=$rx_bytes old_tx_bytes=$tx_bytes rx_bytes=$(cat /sys/class/net/$interface/statistics/rx_bytes) tx_bytes=$(cat /sys/class/net/$interface/statistics/tx_bytes) tx_bytes_rate=$(( ($tx_bytes - $old_tx_bytes) / $interval )) rx_bytes_rate=$(( ($rx_bytes - $old_rx_bytes) / $interval )) done
Você pode colocar esse script em algum lugar do seu $PATH
, torná-lo executável com chmod +x <script>
e testá-lo com script.sh <interface name>
. Aqui está a aparência da saída na minha máquina:
13KiB/s ⬆ 379KiB/s ⬇
Isso é bem legal! Você pode imaginar alguns usos para isso: por exemplo, como um widget para uma ferramenta que pode renderizar a saída do comando ou como uma maneira rápida de observar a atividade de rede para uma interface de rede específica. Em ambos os casos, a interface baseada em arquivo para esses dados torna o acesso e o uso excepcionalmente fácil.
Este foi apenas um pequeno mergulho nos tipos de informações disponíveis à medida que você examina mais profundamente os recursos de um sistema Linux moderno. Você pode procurar por guias adicionais como este ou ir direto à fonte lendo as páginas do man
para entradas como man hier
para ler a função e o propósito de vários diretórios em /
.
Divirta-se explorando!