<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Fernando Mota Freitas - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Fernando Mota Freitas - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 16 May 2026 19:16:36 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/author/fernando/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Como configurar um proxy reverso de modo fácil e seguro com Docker, Nginx e Letsencrypt ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Kasper Siig Introdução Já tentou configurar algum tipo de servidor em casa, onde você tem que abrir uma nova porta para cada serviço? Já teve que lembrar qual porta vai para qual serviço, e qual é o seu IP doméstico? Isso é definitivamente algo que funciona, e as ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-configurar-um-proxy-reverso-de-modo-facil-e-seguro-com-docker-nginx-e-letsencrypt/</link>
                <guid isPermaLink="false">6263eeec6daab205304b2d64</guid>
                
                <dc:creator>
                    <![CDATA[ Fernando Mota Freitas ]]>
                </dc:creator>
                <pubDate>Wed, 27 Apr 2022 13:39:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/04/john-salvino-bqGBbLq_yfc-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/docker-nginx-letsencrypt-easy-secure-reverse-proxy-40165ba3aee2/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to set up an easy and secure reverse proxy with Docker, Nginx &amp; Letsencrypt</a>
      </p><p>Escrito por: Kasper Siig</p><h3 id="introdu-o">Introdução</h3><p>Já tentou configurar algum tipo de servidor em casa, onde você tem que abrir uma nova porta para cada serviço? Já teve que lembrar qual porta vai para qual serviço, e qual é o seu IP doméstico? Isso é definitivamente algo que funciona, e as pessoas fazem isso há muito tempo.</p><p>No entanto, não seria bom digitar <em>plex.example.com</em> e ter acesso instantâneo ao seu servidor de mídia? É exatamente isso que um proxy reverso fará por você, e combiná-lo com o Docker está mais fácil do que nunca.</p><h2 id="pr-requisitos">Pré-requisitos</h2><h3 id="docker-e-docker-compose">Docker e Docker-Compose</h3><p>Você deve ter o Docker versão 17.12.0+ e o docker-compose versão 1.21.0+.</p><h3 id="dom-nio">Domínio</h3><p>Você deve ter um domínio configurado e ter um certificado SSL associado a ele. Se você não tiver um, <a href="https://faun.pub/docker-letsencrypt-dns-validation-75ba8c08a0d">siga meu guia aqui</a> (texto em inglês) sobre como obter um gratuitamente com o LetsEncrypt.</p><h2 id="o-que-este-artigo-abordar-">O que este artigo abordará</h2><p>Acredito firmemente na importância de se entender o que você está fazendo. Houve um tempo em que eu seguia guias e não fazia ideia de como solucionar falhas. Se é assim que você quer fazer isso, <a href="https://medium.freecodecamp.org/docker-compose-nginx-and-letsencrypt-setting-up-website-to-do-all-the-things-for-that-https-7cb0bf774b7e"></a><a href="https://www.freecodecamp.org/news/docker-compose-nginx-and-letsencrypt-setting-up-website-to-do-all-the-things-for-that-https-7cb0bf774b7e">aqui está um ótimo tutorial</a> (em inglês), que aborda como configurá-lo. Embora meus artigos sejam longos, você deve acabar entendendo como tudo funciona.</p><p>O que você aprenderá aqui: o que é um proxy reverso, como configurá-lo e como protegê-lo. Eu tento, da melhor maneira possível, dividir o assunto em seções, as quais estarão divididas por cabeçalhos. Assim, sinta-se à vontade para pular uma seção, se quiser. Eu recomendo ler o artigo inteiro uma vez primeiro, antes de começar a configuração.</p><h2 id="o-que-um-proxy-reverso">O que é um proxy reverso?</h2><h3 id="proxy-comum">Proxy comum</h3><p>Vamos começar com o conceito de um proxy comum. Embora este seja um termo muito prevalente na comunidade de tecnologia, não é o único lugar em que é usado. Um proxy significa que a informação está passando por um terceiro, antes de chegar ao local.</p><p>Digamos que você não queira que um serviço saiba seu IP. Você pode, nesse caso, usar um proxy. Um proxy é um servidor que foi configurado especificamente para essa finalidade. Se o servidor proxy que você está usando estiver localizado, por exemplo, em Amsterdã, o IP que será mostrado para o mundo externo será o IP do servidor em Amsterdã. Os únicos que saberão seu IP são os que controlam o servidor proxy.</p><h3 id="proxy-reverso">Proxy reverso</h3><p>Para simplificar, um proxy adicionará uma camada de mascaramento. É o mesmo conceito em um proxy reverso, excetuando o fato de que, em vez de mascarar as conexões de saída (você acessando um servidor web), são as conexões de entrada (pessoas acessando seu servidor web) que serão mascaradas. Você simplesmente fornece um URL como <em>exemplo.com</em> e, sempre que as pessoas acessarem esse URL, seu proxy reverso cuidará para onde vai essa solicitação.</p><p>Digamos que você tenha dois servidores configurados em sua rede interna. Server1 está em <em>192.168.1.10</em> e Server2 está em <em>192.168.1.20. </em>No momento, seu proxy reverso está enviando solicitações provenientes de <em>exemplo.com</em> para Server1. Um dia, você tem algumas atualizações para a página da web. Em vez de tirar o site do ar para manutenção, basta fazer a nova configuração no Server2. Feito isso, basta alterar uma única linha em seu proxy reverso e agora as solicitações são enviadas para o Server2. Supondo que o proxy reverso esteja configurado corretamente, você não deve ter absolutamente nenhum tempo de inatividade.</p><p>Talvez a maior vantagem de se ter um proxy reverso seja que você pode ter serviços rodando em várias portas, mas só precisa abrir as portas 80 e 443, HTTP e HTTPS, respectivamente. Todas as solicitações chegarão à sua rede nessas duas portas e o proxy reverso cuidará do resto. Tudo isso fará sentido quando começarmos a configurar o proxy.</p><h2 id="configurando-o-cont-iner">Configurando o contêiner</h2><h3 id="o-que-fazer">O que fazer</h3><p><code>docker-compose.yaml</code>:</p><pre><code class="language-yaml">version: '3'

services:
  reverse:
    container_name: reverse
    hostname: reverse
    image: nginx
    ports:
      - 80:80
      - 443:443
    volumes:
      - &lt;caminho/para/seu/config&gt;:/etc/nginx
      - &lt;caminho/para/seus/certificados&gt;:/etc/ssl/private</code></pre><p>Antes de tudo, você deve adicionar um novo serviço ao seu arquivo docker-compose. Você pode chamá-lo como preferir, neste caso eu escolhi "<em>reverse"</em>. Aqui, escolhi <em>nginx</em> como a imagem. No entanto, em um ambiente de produção, geralmente é uma boa ideia especificar uma versão caso haja alguma alteração importante em atualizações futuras.</p><p>Então você deve vincular duas pastas. <em>/etc/nginx</em> é onde todos os seus arquivos de configuração são armazenados e <em>/etc/ssl/private</em> é onde seus certificados SSL são armazenados. É MUITO importante que sua pasta de configuração NÃO exista em seu host na primeira vez em que você iniciar o contêiner. Quando você inicia seu contêiner por meio do docker-compose, ele criará automaticamente a pasta e a preencherá com o conteúdo do contêiner. Se você criou uma pasta de configuração vazia em seu host, ela será montada e a pasta dentro do contêiner estará vazia.</p><h3 id="por-que-funciona">Por que funciona</h3><p>Não há muito nesta parte. Principalmente, é como iniciar qualquer outro contêiner com docker-compose. O que você deve observar aqui é que você está vinculando as portas 80 e 443. É aqui que todas as solicitações entrarão e serão encaminhadas para qualquer serviço que você especificar.</p><h2 id="configurando-o-nginx">Configurando o Nginx</h2><h3 id="o-que-fazer-1">O que fazer</h3><p>Agora, você deve ter uma pasta de configuração em seu host. Mudando para esse diretório, você deve ver vários arquivos diferentes e uma pasta chamada <code>conf.d</code>. É dentro de <code>conf.d</code> que serão colocados todos os seus arquivos de configuração. No momento, há um único arquivo <code>default.conf</code>. Você pode excluí-lo sem problemas.</p><p>Ainda dentro de <code>conf.d</code>, crie duas pastas: <code>sites-available</code> e <code>sites-enabled</code>. Navegue até <code>sites-available</code> e crie seu primeiro arquivo de configuração. Aqui, vamos configurar uma entrada para o <a href="https://plex.tv/"></a><a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://plex.tv" rel="noopener">Plex</a>, mas sinta-se à vontade para usar outro serviço que você configurou, se desejar. Realmente não importa como o arquivo é chamado. Porém, prefiro chamá-lo de <code>plex.conf</code>.</p><p>Abra o arquivo e digite o seguinte:</p><pre><code>upstream plex {
  server        plex:32400;
}

server {
  listen        80;
  server_name   plex.exemplo.com;

  location / {
    proxy_pass  http://plex;
  }
}</code></pre><p>Entre no diretório <code>sites-enabled</code> e digite o seguinte comando:</p><pre><code>ln -s ../sites-available/plex.conf .</code></pre><p>Isso criará um link simbólico para o arquivo na outra pasta. Resta apenas uma coisa, que é mudar o arquivo <code>nginx.conf</code> na pasta config. Se você abrir o arquivo, deverá ver o seguinte como a última linha:</p><pre><code>include /etc/nginx/conf.d/*.conf;</code></pre><p>Altere isso para:</p><pre><code>include /etc/nginx/conf.d/sites-enabled/*.conf;</code></pre><p>Para que o proxy reverso realmente funcione, precisamos recarregar o serviço nginx dentro do contêiner. No host, execute <code>docker exec &lt;nome-do-contêiner&gt; nginx -t</code>. Isso executará um verificador de sintaxe em seus arquivos de configuração. Isso deve mostrar que a sintaxe está correta. Agora, execute <code>docker exec &lt;nome-do-contêiner&gt; nginx -s reload</code>. Isso enviará um sinal para o processo nginx de que ele deve recarregar. Parabéns! Agora você tem um proxy reverso em execução e deve conseguir acessar seu servidor em <em><em>plex.ex</em>emplo<em>.com</em></em> (assumindo que você encaminhou a porta 80 para seu host em seu roteador).</p><p>Mesmo que seu proxy reverso esteja funcionando, você está executando em HTTP, que não fornece criptografia alguma. A próxima parte será como proteger seu proxy e obter uma pontuação perfeita no <a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://www.ssllabs.com/ssltest/analyze.html" rel="noopener"></a><a href="https://www.ssllabs.com/ssltest/analyze.html">SSL Labs</a>.</p><h3 id="por-que-funciona-1">Por que funciona</h3><p><strong>O arquivo de configuração</strong></p><p>Como você pode ver, o arquivo <code>plex.conf</code> consiste em duas partes. Uma parte <code>upstream</code> e uma parte <code>server</code>. Vamos começar com a parte <code>server</code>. É aqui que você está definindo a porta em que recebe as solicitações de entrada, qual domínio essa configuração deve corresponder e para onde deve ser enviada.</p><p>Da forma como este servidor está sendo configurado, você deve criar um arquivo para cada serviço para o qual deseja fazer solicitações de proxy. Então, obviamente, você precisa de alguma maneira de distinguir qual arquivo receberá cada solicitação. É isso que a diretiva <code>server-name</code> faz. Abaixo disso, temos a diretiva <code>location</code>.</p><p>No nosso caso, só precisamos de uma <code>location</code>, mas você pode ter quantas diretivas <code>location</code> quiser. Imagine que você tenha um site com um front-end e um back-end. Dependendo da infraestrutura que estiver usando, você terá o front-end como um contêiner e o back-end como outro contêiner. Você poderia então ter <code>location / {}</code>, que enviará solicitações para o front-end, e <code>location /api/ {}</code>, que enviará solicitações para o back-end. De repente, você tem vários serviços em execução em um único domínio memorável.</p><p>Quanto à parte de <code>upstream</code>, ela pode ser usada para balanceamento de carga. Se você estiver interessado em saber mais sobre como isso funciona, consulte a <a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=http://nginx.org/en/docs/http/ngx_http_upstream_module.html">documentação oficial aqui</a>. Para o nosso caso simples, você apenas define o nome do host ou endereço IP do serviço para o qual deseja fazer proxy, e qual porta deve ser a proxy. Em seguida, direcione ao nome do upstream na diretiva <code>location</code>.</p><p><strong>Nome do host x endereço IP</strong></p><p>Para entender o que é um hostname, vamos pensar em um exemplo. Digamos que você esteja em sua rede doméstica <em>192.168.1.0. </em>Você, então, configura um servidor em <em>192.168.1.10</em> e executa o Plex nele. Agora, você pode acessar o Plex em <em>192.168.1.10:32400</em>, desde que ainda esteja na mesma rede. Outra possibilidade é dar ao servidor um nome de host. Nesse caso, daremos o nome de host <em>plex</em>. Agora, você pode acessar o Plex digitando <em>plex:32400</em> no seu navegador!</p><p>Esse mesmo conceito foi introduzido no docker-compose na versão 3. Se você observar o arquivo docker-compose anteriormente neste artigo, notará que dei a ele uma diretiva <code>hostname: reverse</code>. Agora todos os outros contêineres podem acessar meu proxy reverso por seu nome de host. Uma coisa que é muito importante observar é que o nome do serviço deve ser o mesmo que o nome do host. Isso é algo que os criadores do docker-compose escolheram impor.</p><p>Outra coisa realmente importante a ser lembrada é que, por padrão, os contêineres do docker são colocados em sua própria rede. Isso significa que você não poderá acessar seu contêiner pelo nome do host, se estiver usando o laptop na rede do host. São apenas os contêineres que podem acessar uns aos outros por meio de seu nome de host.</p><p>Então, para resumir e deixar bem claro. Em seu arquivo docker-compose, adicione a diretiva <code>hostname</code> aos seus serviços. Na maioria das vezes, seus contêineres receberão um novo IP toda vez que você reiniciar o contêiner. Portanto, referir-se a ele por meio do nome do host significa que não importa qual IP seu contêiner está recebendo.</p><p><strong>sites-available e sites-enabled</strong></p><p>Por que estamos criando os diretórios <code>sites-available</code> e <code>sites-enabled</code>? Isso não é algo da minha criação. Se você instalar o Nginx em um servidor, verá que ele vem com essas pastas. No entanto, como o Docker é construído com microsserviços em mente, onde um contêiner deve fazer apenas uma coisa, essas pastas são omitidas no contêiner. Estamos recriando-as novamente, por causa da maneira como estamos usando o contêiner.</p><p>E, sim, você definitivamente pode criar uma pasta <code>sites-enabled</code> ou hospedar diretamente seus arquivos de configuração em <code>conf.d</code>. Fazendo desta forma, você pode ter uma configuração passiva. Digamos que você está fazendo a manutenção e não quer ter o serviço ativo; você simplesmente remove o link simbólico e o coloca de volta quando quiser que o serviço fique ativo novamente.</p><p><strong>Links simbólicos</strong></p><p>Links simbólicos são um recurso muito poderoso do sistema operacional. Eu pessoalmente nunca os usei antes de configurar um servidor Nginx, mas desde então os tenho usado em todos os lugares que posso. Digamos que você esteja trabalhando em 5 projetos diferentes, mas todos esses projetos usam o mesmo arquivo de alguma forma. Você pode copiar o arquivo em cada projeto e consultá-lo diretamente, ou pode colocar o arquivo em um local e, nesses 5 projetos, criar links simbólicos para esse arquivo.</p><p>Isso oferece duas vantagens: você ocupa 4 vezes menos espaço do que teria de outra forma e - o motivo mais poderoso de todos: muda o arquivo em um só lugar e ele muda em todos os 5 projetos de uma vez! Isso não tem muito a ver com o tópico do artigo, mas acho que vale a pena mencionar.</p><h2 id="protegendo-o-proxy-nginx">Protegendo o proxy Nginx</h2><h3 id="o-que-fazer-2">O que fazer</h3><p>Vá para sua pasta de configuração, crie 3 arquivos e preencha-os com o seguinte :</p><p><code>common.conf</code>:</p><pre><code>add_header Strict-Transport-Security    "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options              SAMEORIGIN;
add_header X-Content-Type-Options       nosniff;
add_header X-XSS-Protection             "1; mode=block";</code></pre><p><code>common_location.conf</code>:</p><pre><code>proxy_set_header    X-Real-IP           $remote_addr;
proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
proxy_set_header    X-Forwarded-Proto   $scheme;
proxy_set_header    Host                $host;
proxy_set_header    X-Forwarded-Host    $host;
proxy_set_header    X-Forwarded-Port    $server_port;</code></pre><p><code>ssl.conf</code>:</p><pre><code>ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;
ssl_ecdh_curve              secp384r1;
ssl_ciphers                 "ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384 OLD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 OLD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
ssl_prefer_server_ciphers   on;
ssl_dhparam                 /etc/nginx/dhparams.pem;
ssl_certificate             /etc/ssl/private/fullchain.pem;
ssl_certificate_key         /etc/ssl/private/privkey.pem;
ssl_session_timeout         10m;
ssl_session_cache           shared:SSL:10m;
ssl_session_tickets         off;
ssl_stapling                on;
ssl_stapling_verify         on;</code></pre><p>Agora, abra o arquivo <code>plex.conf</code> e altere-o para o seguinte (observe as linhas 6, 9, 10 e 14):</p><pre><code>upstream plex {
  server        plex:32400;
}

server {
  listen        443 ssl;
  server_name   plex.example.com;

  include       common.conf;
  include       /etc/nginx/ssl.conf;

  location / {
    proxy_pass  http://plex;
    include     common_location.conf;
  }
}</code></pre><p>Agora, volte para a raiz da sua pasta de configuração e execute o seguinte comando:</p><pre><code>openssl dhparam -out dhparams.pem 4096</code></pre><p>Isso levará muito tempo para ser concluído (até uma hora, em alguns casos).</p><p>Se você seguiu meu artigo sobre como obter um certificado SSL LetsEncrypt, seus certificados devem estar localizados em <code>&lt;/caminho/para/seu/letsencrypt/config&gt;/etc/letsencrypt/live/&lt;domínio&gt;/</code>.</p><p>Quando ajudei um amigo a configurar isso em seu sistema, tivemos alguns problemas em que não foi possível abrir os arquivos quando eles estavam localizados nesse diretório. Provavelmente, a causa disso foram alguns problemas de permissões. A solução fácil para isso é criar um diretório SSL, como <code>&lt;/caminho/para/seu/nginx/config&gt;/certs</code>, e montá-lo na pasta <code>/etc/ssl/private</code> do contêiner Nginx. Na pasta recém-criada, você deve criar links simbólicos para os certificados na pasta de configuração do LetsEncrypt.</p><p>Quando o comando <code>openssl</code> terminar de ser executado, você deve executar o <code>docker exec &lt;nome-do-contêiner&gt; nginx -t</code> para se certificar de que toda a sintaxe está correta e, em seguida, recarregá-lo executando <code>docker exec &lt;nome-do-contêiner&gt; nginx -s reload</code>. Neste ponto, tudo deve estar funcionando e, agora, você tem um proxy reverso funcionando e perfeitamente seguro!</p><h3 id="por-que-funciona-2">Por que funciona</h3><p>Olhando no arquivo <code>plex.conf</code>, há apenas uma grande mudança - em qual porta o proxy reverso está escutando e informando que é uma conexão SSL. Depois, há 3 lugares onde estamos incluindo os outros 3 arquivos que criamos. Embora o SSL seja, de certo modo, seguro por si só, esses outros arquivos o tornam ainda mais seguro. No entanto, se por algum motivo você não quiser incluir esses arquivos, será necessário mover o <code>ssl-certificate</code> e <code>ssl-certificate-key</code> dentro do &nbsp;arquivo<code>.conf</code>. Eles são necessários para que uma conexão HTTPS funcione.</p><p><strong>Common.conf</strong></p><p>Olhando no arquivo <code>common.conf</code>, adicionamos 4 cabeçalhos diferentes. Os cabeçalhos são algo que o servidor envia ao navegador em cada resposta. Esses cabeçalhos dizem ao navegador para agir de uma determinada maneira e, então, cabe ao navegador impor esses cabeçalhos.</p><p><strong><a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Headers/Strict-Transport-Security">Strict-Transport-Security (HSTS)</a></strong></p><p>Este cabeçalho informa ao navegador que as conexões devem ser feitas por HTTPS. Quando esse cabeçalho for adicionado, o navegador não permitirá que você faça uma conexão HTTP simples com o servidor, garantindo que toda a comunicação seja segura.</p><p><strong><a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Headers/X-Frame-Options">X-Frame-Options</a></strong></p><p>Ao especificar esse cabeçalho, você especifica se outros sites podem ou não incorporar seu conteúdo em seus sites. Isso pode ajudar a evitar ataques de <a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://en.wikipedia.org/wiki/Clickjacking" rel="noopener"></a><a href="https://pt.wikipedia.org/wiki/Clickjacking">clickjacking</a>.</p><p><a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options" rel="noopener"><strong></strong></a><strong><a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Headers/X-Content-Type-Options">X-Content-Type-Options</a></strong></p><p>Digamos que você tenha um site onde os usuários possam fazer upload de arquivos. Não há validação suficiente nos arquivos, então um usuário carrega com sucesso um arquivo <code>php</code> para o servidor, onde o servidor espera que uma imagem seja carregada. O invasor pode então acessar o arquivo carregado. Agora, o servidor responde com uma imagem, porém o tipo MIME do arquivo é <code>text/plain</code>. O navegador fará o 'sniffing' do arquivo e renderizará o script php, permitindo que o invasor faça RCE (Remote Code Execution).</p><p>Com este cabeçalho definido como 'nosniff', o navegador não examinará o arquivo e simplesmente o renderizará como o que o servidor disser ao navegador que ele é.</p><p><a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection" rel="noopener"><strong></strong></a><strong><a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Headers/X-XSS-Protection">X-XSS-Protection</a></strong></p><p>Embora esse cabeçalho fosse mais necessário em navegadores mais antigos, é tão fácil de adicionar que você também pode. Alguns ataques XSS (Cross-site Scripting) podem ser muito inteligentes, enquanto alguns são muito rudimentares. Este cabeçalho dirá aos navegadores para verificar as vulnerabilidades simples e bloqueá-las.</p><p><strong><strong>Common_location.conf</strong></strong></p><p><strong>X-Real-IP</strong></p><p>Como seus servidores estão atrás de um proxy reverso, se você tentar ver o IP solicitante, sempre verá o IP do proxy reverso. Este cabeçalho é adicionado para que você possa ver qual IP está realmente solicitando seu serviço.</p><p><strong><strong>X-Forwarded-For</strong></strong></p><p>Às vezes, uma solicitação de usuário passará por vários clients antes de chegar ao seu servidor. Este cabeçalho inclui um array de todos esses clients.</p><p><strong>X-Forwarded-Proto</strong></p><p>Este cabeçalho mostrará qual protocolo está sendo usado entre client e servidor.</p><p><strong>Host</strong></p><p>Isso garante que seja possível fazer uma pesquisa de DNS reversa no nome de domínio. É usado quando a diretiva <code>server_name</code> é diferente daquela para a qual você está fazendo proxy.</p><p><strong><strong>X-Forwarded-Host</strong></strong></p><p>Mostra qual é o host real da solicitação em vez do proxy reverso.</p><p><strong>X-Forwarded-Port</strong></p><p>Ajuda a identificar em qual porta o client solicitou o servidor.</p><p><strong>SSL.conf</strong></p><p>SSL é um tópico enorme por si só, e grande demais para começar a explicar neste artigo. Existem muitos tutoriais excelentes sobre como os handshakes de SSL funcionam e assim por diante. Se você quiser examinar esse arquivo específico, sugiro examinar os protocolos e cifras que estão sendo usados ​​e qual a diferença que eles fazem.</p><h2 id="redirecionando-http-para-https">Redirecionando HTTP para HTTPS</h2><p>Os observadores talvez tenham notado que estamos ouvindo apenas na porta 443 nesta versão segura. Isso significaria que qualquer pessoa que tentasse acessar o site via <em>https://*</em> passaria, mas tentar se conectar através de <em>http://*</em> receberia apenas um erro. Felizmente, há uma solução muito fácil para isso. Crie um arquivo <code>redirect.conf</code> com o seguinte conteúdo:</p><pre><code>server {
  listen        80;

  server_name   _;

  return 301 https://$host$request_uri;
}</code></pre><p>Agora, apenas certifique-se de que ele apareça em sua pasta <code>sites-enabled</code> e, quando você recarregar o processo Nginx no contêiner, todas as solicitações para a porta 80 serão redirecionadas para a porta 443 (HTTPS).</p><h2 id="pensamentos-finais">Pensamentos finais</h2><p>Agora que seu site está funcionando, você pode acessar o <a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://www.ssllabs.com/ssltest/analyze.html" rel="noopener"></a><a href="https://www.ssllabs.com/ssltest/analyze.html">SSL Labs</a> e fazer um teste para ver o nível de segurança de seu site. No momento em que escrevo isso, você deve obter uma pontuação perfeita. No entanto, há algo importante a se notar sobre isso.</p><p>Sempre haverá um equilíbrio entre segurança e conveniência. Neste caso, os pesos estão muito do lado da segurança. Se você executar o teste no SSL Labs e rolar para baixo, verá que há vários dispositivos que não poderão se conectar ao seu site porque não suportam novos padrões.</p><p>Portanto, tenha isso em mente quando estiver fazendo essa configuração. No momento, estou apenas executando um servidor em casa, onde não preciso me preocupar com tantas pessoas podendo acessá-lo. Mas se você fizer uma varredura no Facebook, verá que o site não terá uma pontuação tão boa, porém pode ser acessado por mais dispositivos.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Guia de instalação do Vim no Windows – como executar o editor de texto Vim no PowerShell do seu PC ]]>
                </title>
                <description>
                    <![CDATA[ O Vim é um editor de código poderoso. Tão poderoso que tanto o Linux quanto o Mac o têm instalado por padrão. Mas se você estiver usando o Windows como sistema operacional, precisará instalar o Vim separadamente. Felizmente, a Microsoft torna muito fácil instalar o Vim e executá-lo no seu ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/guia-de-instalacao-do-vim-no-windows-como-executar-o-editor-de-texto-vim-no-powershell-do-seu-pc/</link>
                <guid isPermaLink="false">621687fb9838eb04fbdf1388</guid>
                
                    <category>
                        <![CDATA[ Vim ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Fernando Mota Freitas ]]>
                </dc:creator>
                <pubDate>Thu, 24 Feb 2022 01:09:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/5f9c9b34740569d1a4ca2a64.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/vim-windows-install-powershell/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Vim Windows Install Guide – How to Run the Vim Text Editor in PowerShell on your PC</a>
      </p><p>O Vim é um editor de código poderoso. Tão poderoso que tanto o Linux quanto o Mac o têm instalado por padrão.</p><p>Mas se você estiver usando o Windows como sistema operacional, precisará instalar o Vim separadamente.</p><p>Felizmente, a Microsoft torna muito fácil instalar o Vim e executá-lo no seu PC.</p><h2 id="como-baixar-o-vim">Como baixar o Vim</h2><p>Você pode <a href="https://www.vim.org/download.php">baixar a versão mais recente do Vim Text Editor diretamente do próprio Vim</a>.</p><p>Eles criaram um instalador autoexecutável especial, que o orienta no processo de instalação do Vim no local certo em seu disco rígido.</p><h2 id="como-instalar-o-vim">Como instalar o Vim</h2><p>Observe que, para o Windows, você tecnicamente baixará algo chamado gVim, que é uma versão do Vim que inclui uma interface gráfica de usuário básica (GUI). Você pode <a href="https://ftp.nluug.nl/pub/vim/pc/gvim82.exe">instalá-la baixando este instalador executável</a> .</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/signal-attachment-2020-05-07-144326_005-1.png" class="kg-image" alt="signal-attachment-2020-05-07-144326_005-1" width="508" height="253" loading="lazy"><figcaption>Uma imagem do que você verá ao tentar abrir o arquivo. Como ele é um arquivo .exe, o Windows pedirá sua permissão primeiro.</figcaption></figure><p>Depois de baixar o arquivo, basta executá-lo e você verá um assistente de instalação idêntico ao mostrado abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/signal-attachment-2020-05-07-144326_004.png" class="kg-image" alt="signal-attachment-2020-05-07-144326_004" width="541" height="433" loading="lazy"><figcaption>Uma captura de tela do assistente que você verá quando executar o instalador do Vim pela primeira vez</figcaption></figure><p>Eles têm uma instalação "típica" recomendada. mas se você tiver um disco rígido razoavelmente grande, não há mal nenhum em prosseguir com a instalação de tudo escolhendo a opção "completo":</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/signal-attachment-2020-05-07-144326_003.png" class="kg-image" alt="signal-attachment-2020-05-07-144326_003" width="534" height="418" loading="lazy"><figcaption>Uma captura de tela do instalador do Vim, onde você pode escolher quais partes do Vim você deseja instalar.</figcaption></figure><h2 id="como-executar-o-vim-no-powershell">Como executar o Vim no PowerShell</h2><p>Então, depois de instalar o Vim, você poderá iniciá-lo no prompt de comando do Windows.</p><p>Observe que, a partir de 2020, o PowerShell tem todas as mesmas funcionalidades do CMD, além de muito mais. Eu recomendo usar o PowerShell para tudo.</p><p>Você pode abrir o PowerShell na barra de menus do Windows digitando "powershell" no campo de pesquisa na barra inicial.</p><p>O Windows abrirá o PowerShell e você receberá um prompt de comando semelhante a este:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/signal-attachment-2020-05-07-144326_001-1.png" class="kg-image" alt="signal-attachment-2020-05-07-144326_001-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/signal-attachment-2020-05-07-144326_001-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/signal-attachment-2020-05-07-144326_001-1.png 883w" sizes="(min-width: 720px) 720px" width="883" height="742" loading="lazy"><figcaption>Uma captura de tela do prompt do PowerShell do Windows.</figcaption></figure><p>Veja aqui como executar o Vim quando estiver no PowerShell. Tudo o que você precisa fazer é digitar "vim" e pressionar Enter. Isso abrirá o Vim. Uma vez que o Vim estiver aberto, isto é o que você deve ver:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/signal-attachment-2020-05-07-144326_002.png" class="kg-image" alt="signal-attachment-2020-05-07-144326_002" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/signal-attachment-2020-05-07-144326_002.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/signal-attachment-2020-05-07-144326_002.png 858w" sizes="(min-width: 720px) 720px" width="858" height="751" loading="lazy"><figcaption>Uma captura de tela do Vim quando você o abre pela primeira vez.</figcaption></figure><p>Parabéns – agora você tem o Vim instalado.</p><h2 id="como-executar-o-vim-dentro-do-vs-code">Como executar o Vim dentro do VS Code</h2><p>Se você já está usando o VS Code, e quer a grande velocidade do Vim sem perder a funcionalidade do VS Code, tenho boas notícias. É possível executar uma experiência semelhante ao Vim diretamente no VS Code.</p><p><a href="https://marketplace.visualstudio.com/items?itemName%3Dvscodevim.vim">Aqui está um plug-in do Vim para o VS Code</a> que o ajudará a fazer isso. No momento em que escrevi este artigo, o plug-in já havia sido instalado quase 2 milhões de vezes.</p><h2 id="como-aprender-a-usar-o-vim-corretamente">Como aprender a usar o Vim corretamente</h2><p>O Vim é um editor de código poderoso e você precisará de muita prática para se acostumar com ele.</p><p>Aqui estão alguns tutoriais do Vim que realmente ajudarão você a entender rapidamente o básico e fazer seus dedos voarem rapidamente.</p><p>Para começar, uma maneira que o Vim é diferente de outros editores de código é que o Vim tem "modos". Aqui estão <a href="https://www.freecodecamp.org/news/vim-editor-modes-explained/">todos os modos do Vim explicados, com exemplos</a> (texto em inglês).</p><p>O Vim pode ser intimidante. Há muito o que aprender. Mas este guia mostrará <a href="https://www.freecodecamp.org/news/how-not-to-be-afraid-of-vim-anymore-ec0b7264b0ae/">como não ter mais medo do Vim</a> (texto em inglês).</p><p>Se você já estiver usando o VS Code e quiser mudar completamente para o Vim, <a href="https://www.freecodecamp.org/news/vim-for-people-who-use-visual-studio-code/">este artigo explicará como você pode fazer isso</a> (texto em inglês).</p><p>E <a href="https://www.freecodecamp.org/news/7-vim-tips-that-changed-my-life/">aqui estão 7 dicas do Vim que mudaram a vida do criador do #100DaysOfCode, Alex Kallaway</a> (texto em inglês). Neste artigo, ele não apenas explica isso, mas mostra demonstrações dessas dicas em ação.</p><h2 id="vim-aprenda-viva-ame-">Vim: aprenda, viva, ame.</h2><p>Nos 30 anos desde que Bram Moolenaar criou o Vim, sua influência se espalhou por toda parte. Ainda hoje, o projeto Vim é mantido ativamente e melhorando constantemente.</p><p>Eu conheci tantos desenvolvedores ao longo dos anos que botam a mão no fogo pelo Vim.</p><p>Espero que este guia tenha ajudado você a executar o Vim no seu PC com Windows. E espero que esses outros tutoriais que compartilhei com você aqui ajudem você a ir do zero à prática nos próximos meses.</p><p>A chave é continuar praticando e não desanimar com a quantidade de atalhos a serem lembrados no Vim. Eventualmente, tudo isso se tornará memória muscular, e você estará voando de um arquivo para outro, acabando com qualquer código, feito um exterminador.</p><p>Não há sensação tão legal quanto a de ser capaz de entrar em uma base de código e começar imediatamente a fazer alterações sem sequer pegar um mouse ou trackpad. Esse é o poder que o Vim promete e entrega com sobras.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Comandos básicos em SQL - A lista de consultas e instruções de banco de dados que você deve conhecer ]]>
                </title>
                <description>
                    <![CDATA[ SQL significa Linguagem de Consulta Estruturada (Structured Query Language em inglês). Os comandos SQL são as instruções usadas para se comunicar com um banco de dados para executar tarefas, funções e consultas com dados. Os comandos do SQL podem ser usados ​​para pesquisar o banco de dados e realizar outras ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/comandos-basicos-em-sql-a-lista-de-consultas-e-instrucoes-de-banco-de-dados-que-voce-deve-conhecer/</link>
                <guid isPermaLink="false">6208eecccfef2204db7ee04f</guid>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Fernando Mota Freitas ]]>
                </dc:creator>
                <pubDate>Sat, 19 Feb 2022 22:36:25 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/artigo3-sql-basics-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/basic-sql-commands/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Basic SQL Commands - The List of Database Queries and Statements You Should Know</a>
      </p><p>SQL significa Linguagem de Consulta Estruturada (Structured Query Language em inglês). Os comandos SQL são as instruções usadas para se comunicar com um banco de dados para executar tarefas, funções e consultas com dados.</p><p>Os comandos do SQL podem ser usados ​​para pesquisar o banco de dados e realizar outras funções, como criar tabelas, adicionar dados a tabelas, modificar dados e descartar tabelas.</p><p>Aqui está uma lista de comandos SQL básicos (às vezes chamados de instruções) que você deve saber se vai trabalhar com SQL.</p><h3 id="select-e-from"><strong>SELECT e FROM</strong></h3><p>A parte <code>SELECT</code> (selecionar, em inglês) de uma consulta determina quais colunas dos dados serão exibidas nos resultados. Também há opções que você pode aplicar para mostrar dados que não são uma coluna da tabela.</p><p>O exemplo abaixo mostra três colunas selecionadas na tabela "student" (aluno, em inglês), para isso usamos o comando <code>FROM</code> (vindo de, em inglês) e uma coluna calculada. O banco de dados armazena o studentID, FirstName e LastName do aluno (id do aluno, nome e sobrenome em inglês, respectivamente). Podemos combinar as colunas FirstName e LastName para criar a coluna calculada FullName. (nome completo, em inglês)‌. </p><pre><code class="language-sql">SELECT studentID, FirstName, LastName, FirstName + ' ' + LastName AS FullName
FROM student;</code></pre><pre><code class="language-text">+-----------+-------------------+------------+------------------------+
| studentID | FirstName         | LastName   | FullName               |
+-----------+-------------------+------------+------------------------+
|         1 | Monique           | Davis      | Monique Davis          |
|         2 | Teri              | Gutierrez  | Teri Gutierrez         |
|         3 | Spencer           | Pautier    | Spencer Pautier        |
|         4 | Louis             | Ramsey     | Louis Ramsey           |
|         5 | Alvin             | Greene     | Alvin Greene           |
|         6 | Sophie            | Freeman    | Sophie Freeman         |
|         7 | Edgar Frank "Ted" | Codd       | Edgar Frank "Ted" Codd |
|         8 | Donald D.         | Chamberlin | Donald D. Chamberlin   |
|         9 | Raymond F.        | Boyce      | Raymond F. Boyce       |
+-----------+-------------------+------------+------------------------+
9 rows in set (0.00 sec)</code></pre><h3 id="create-table"><strong><strong><strong>CREATE TABLE</strong></strong></strong></h3><p><code>CREATE TABLE</code> (criar tabela, em inglês) faz exatamente o que parece: cria uma tabela no banco de dados. Você pode especificar o nome da tabela e as colunas que devem estar nela.</p><pre><code class="language-sql">CREATE TABLE nome_da_tabela (
    coluna_1 tipo_de_dados,
    coluna_2 tipo_de_dados,
    coluna_3 tipo_de_dados
);</code></pre><h3 id="alter-table">ALTER TABLE</h3><p><a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://dev.mysql.com/doc/refman/5.7/en/alter-table.html"><code>ALTER TABLE</code></a> (alterar tabela, em inglês) altera a estrutura de uma tabela. Aqui está demonstrado como você adicionaria uma coluna a um banco de dados:</p><pre><code class="language-sql">ALTER TABLE nome_da_tabela
ADD coluna tipo_de_dados;</code></pre><h3 id="check">CHECK</h3><p>A instrução <code>CHECK</code> (verificar, em inglês) é usada para limitar o intervalo de valores que pode ser colocado em uma coluna.</p><p>Se você definir uma instrução <code>CHECK</code> em uma única coluna, ela permitirá apenas determinados valores para essa coluna. Se você definir uma instrução <code>CHECK</code> em uma tabela, ela poderá limitar os valores em determinadas colunas com base nos valores de outras colunas dessa linha.</p><p>O SQL a seguir cria uma instrução <code>CHECK</code> na coluna "Age" (idade, em inglês) quando a tabela "Persons" (pessoas, em inglês) é criada. <code>CHECK</code> garante que você não tenha pessoas com menos de 18 anos.‌</p><pre><code class="language-sql">CREATE TABLE Persons (
    ID int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int,
    CHECK (Age&gt;=18)
);</code></pre><p>Para permitir a nomeação de uma instrução <code>CHECK</code> e para definir uma instrução <code>CHECK</code> em várias colunas, use a seguinte sintaxe no SQL:</p><pre><code class="language-sql">CREATE TABLE Persons (
    ID int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int,
    City varchar(255),
    CONSTRAINT CHK_Person CHECK (Age&gt;=18 AND City='Sandnes')
);</code></pre><h2 id="-where">‌WHERE</h2><p><strong><strong><strong>(</strong></strong><code>AND</code> ,<code>OR</code><strong><strong> , <code>IN</code>, <code>BETWEEN</code></strong></strong> </strong>e<strong><strong><strong> <code>LIKE</code>)</strong></strong></strong></p><p>A instrução <code>WHERE</code> (onde, em inglês) é usada para limitar o número de linhas retornadas.</p><p>Como exemplo, primeiro mostraremos uma instrução <code>SELECT</code> e resultados <em>sem</em> declaração <code>WHERE</code>. Em seguida, adicionaremos uma instrução <code>WHERE</code> que usa todos os cinco qualificadores acima.‌ &nbsp; </p><pre><code class="language-sql">SELECT studentID, FullName, sat_score, rcd_updated FROM student;</code></pre><pre><code class="language-text">+-----------+------------------------+-----------+---------------------+
| studentID | FullName               | sat_score | rcd_updated         |
+-----------+------------------------+-----------+---------------------+
|         1 | Monique Davis          |       400 | 2017-08-16 15:34:50 |
|         2 | Teri Gutierrez         |       800 | 2017-08-16 15:34:50 |
|         3 | Spencer Pautier        |      1000 | 2017-08-16 15:34:50 |
|         4 | Louis Ramsey           |      1200 | 2017-08-16 15:34:50 |
|         5 | Alvin Greene           |      1200 | 2017-08-16 15:34:50 |
|         6 | Sophie Freeman         |      1200 | 2017-08-16 15:34:50 |
|         7 | Edgar Frank "Ted" Codd |      2400 | 2017-08-16 15:35:33 |
|         8 | Donald D. Chamberlin   |      2400 | 2017-08-16 15:35:33 |
|         9 | Raymond F. Boyce       |      2400 | 2017-08-16 15:35:33 |
+-----------+------------------------+-----------+---------------------+
9 rows in set (0.00 sec)</code></pre><p>Agora, repetiremos a consulta <code>SELECT</code>, mas limitaremos as linhas retornadas usando uma instrução <code>WHERE</code>.</p><pre><code class="language-sql">STUDENT studentID, FullName, sat_score, recordUpdated
FROM student
WHERE (studentID BETWEEN 1 AND 5 OR studentID = 8)
        AND
        sat_score NOT IN (1000, 1400);</code></pre><pre><code class="language-text">+-----------+----------------------+-----------+---------------------+
| studentID | FullName             | sat_score | rcd_updated         |
+-----------+----------------------+-----------+---------------------+
|         1 | Monique Davis        |       400 | 2017-08-16 15:34:50 |
|         2 | Teri Gutierrez       |       800 | 2017-08-16 15:34:50 |
|         4 | Louis Ramsey         |      1200 | 2017-08-16 15:34:50 |
|         5 | Alvin Greene         |      1200 | 2017-08-16 15:34:50 |
|         8 | Donald D. Chamberlin |      2400 | 2017-08-16 15:35:33 |
+-----------+----------------------+-----------+---------------------+
5 rows in set (0.00 sec)</code></pre><h2 id="update">UPDATE</h2><p>Para atualizar um registro em uma tabela, você usa a instrução <code>UPDATE</code> (atualizar, em inglês).</p><p>Use a instrução <code>WHERE</code> para especificar quais registros você deseja atualizar. É possível atualizar uma ou mais colunas por vez. A sintaxe é:‌ </p><pre><code class="language-sql">UPDATE nome_da_tabela
SET coluna1 = valor1, 
    coluna2 = valor2, ...
WHERE condição;</code></pre><p>Aqui está um exemplo atualizando Name (nome, em inglês) do registro com Id 4:‌ &nbsp; </p><pre><code class="language-sql">UPDATE Person
SET Name = "Elton John"
WHERE Id = 4;</code></pre><p>Você também pode atualizar colunas em uma tabela usando valores de outras tabelas. Use a instrução <code>JOIN</code> (unir, em inglês) para obter dados de várias tabelas. A sintaxe é:</p><pre><code class="language-sql">UPDATE nome_da_tabela1
SET nome_da_tabela1.coluna1 = nome_da_tabela2.colunaA
    nome_da_tabela1.coluna2 = nome_da_tabela2.colunaB
FROM nome_da_tabela1
JOIN nome_da_tabela2 ON nome_da_tabela1.ChaveEstrangeira = nome_da_tabela2.Chave</code></pre><p>Aqui está um exemplo de atualização de Manager (gerenciador, em inglês) de todos os registros:‌ &nbsp; &nbsp; &nbsp;</p><pre><code class="language-sql">UPDATE Person
SET Person.Manager = Department.Manager
FROM Person
JOIN Department ON Person.DepartmentID = Department.ID</code></pre><h2 id="group-by">GROUP BY</h2><p><code>GROUP BY</code> (agrupar por, em inglês) permite combinar linhas e agregar dados.</p><p>Aqui está a sintaxe de <code>GROUP BY</code>:‌ &nbsp; &nbsp;</p><pre><code class="language-sql">SELECT nome_da_coluna, COUNT(*)
FROM nome_da_tabela
GROUP BY nome_da_coluna;</code></pre><h2 id="having">HAVING</h2><p><code>HAVING</code> (contendo, em inglês) permite filtrar os dados agregados pela instrução <code>GROUP BY</code> para que o usuário obtenha um conjunto limitado de registros para visualização.</p><p>Aqui está a sintaxe de <code>HAVING</code>:‌ &nbsp;</p><pre><code class="language-sql">SELECT nome_da_coluna, COUNT(*)
FROM nome_da_tabela
GROUP BY nome_da_coluna
HAVING COUNT(*) &gt; valor;</code></pre><h2 id="avg-">AVG()</h2><p>"Average" (média, em inglês) é usado para calcular a média de uma coluna numérica do conjunto de linhas retornado por uma instrução SQL.</p><p>Aqui está a sintaxe para usar a função:‌ </p><pre><code class="language-sql">SELECT campoAgrupamento, AVG(num_campo)
FROM tabela1
GROUP BY campoAgrupamento</code></pre><p>Aqui está um exemplo usando a tabela de alunos:‌ &nbsp;</p><pre><code class="language-sql">SELECT studentID, FullName, AVG(sat_score) 
FROM student 
GROUP BY studentID, FullName;</code></pre><h2 id="as">AS</h2><p><code>AS</code> (como, em inglês - similar a <em>like</em>, que vemos posteriormente) permite renomear uma coluna ou tabela usando um alias.‌ &nbsp;</p><pre><code class="language-sql">SELECT user_only_num1 AS AgeOfServer, (user_only_num1 - warranty_period) AS NonWarrantyPeriod FROM server_table</code></pre><p>Isso resulta na saída abaixo.‌</p><pre><code class="language-text">+-------------+------------------------+
| AgeOfServer | NonWarrantyPeriod      | 
+-------------+------------------------+
|         36  |                     24 |
|         24  |                     12 | 
|         61  |                     49 |
|         12  |                      0 | 
|          6  |                     -6 |
|          0  |                    -12 | 
|         36  |                     24 |
|         36  |                     24 | 
|         24  |                     12 | 
+-------------+------------------------+</code></pre><p> Você também pode usar AS para atribuir um nome a uma tabela para facilitar a referência em junções.‌ &nbsp; </p><pre><code class="language-sql">SELECT ord.product, ord.ord_number, ord.price, cust.cust_name, cust.cust_number FROM customer_table AS cust

JOIN order_table AS ord ON cust.cust_number = ord.cust_number</code></pre><p>Isso resulta na saída como abaixo.</p><pre><code class="language-text">+-------------+------------+-----------+-----------------+--------------+
| product     | ord_number | price     | cust_name       | cust_number  |
+-------------+------------+-----------+-----------------+--------------+
|     RAM     |   12345    |       124 | John Smith      |  20          |
|     CPU     |   12346    |       212 | Mia X           |  22          |
|     USB     |   12347    |        49 | Elise Beth      |  21          |
|     Cable   |   12348    |         0 | Paul Fort       |  19          |
|     Mouse   |   12349    |        66 | Nats Back       |  15          |
|     Laptop  |   12350    |       612 | Mel S           |  36          |
|     Keyboard|   12351    |        24 | George Z        |  95          |
|     Keyboard|   12352    |        24 | Ally B          |  55          |
|     Air     |   12353    |        12 | Maria Trust     |  11          |
+-------------+------------+-----------+-----------------+--------------+</code></pre><h2 id="order-by">ORDER BY</h2><p><code>ORDER BY</code> (ordenar por, em inglês) nos dá uma maneira de classificar o conjunto de resultados por um ou mais itens na seção <code>SELECT</code>. Aqui está um SQL classificando os alunos por FullName em ordem decrescente. A ordem de classificação padrão é crescente (<code>ASC</code>), mas, para classificar na ordem oposta (decrescente), você usa <code>DESC</code>.‌ &nbsp;</p><pre><code class="language-sql">SELECT studentID, FullName, sat_score
FROM student
ORDER BY FullName DESC;</code></pre><h2 id="count">COUNT</h2><p><code>COUNT</code> (contar, em inglês) contará o número de linhas e retornará essa contagem como uma coluna no conjunto de resultados.</p><p>Aqui estão alguns exemplos onde você usaria COUNT:</p><ul><li>Para contar todas as linhas em uma tabela (GROUP BY não é obrigatório)</li><li>Para contar os totais de subconjuntos de dados (requer um GROUP BY na instrução)</li></ul><p>Essa instrução SQL fornece uma contagem de todas as linhas. Observe que você pode dar um nome à coluna COUNT resultante usando "AS".‌ &nbsp; </p><pre><code class="language-sql">SELECT count(*) AS studentCount FROM student; </code></pre><h2 id="delete">DELETE</h2><p><code>DELETE</code> (excluir, em inglês) é usado para excluir um registro em uma tabela.</p><p>Tome cuidado. Você pode excluir todos os registros da tabela ou apenas alguns deles. Use a condição <code>WHERE</code> para especificar quais registros você deseja excluir. A sintaxe é:‌</p><pre><code class="language-sql">DELETE FROM table_name
WHERE condition;</code></pre><p>Aqui está um exemplo de exclusão do registro com Id 3 na tabela Person:‌</p><pre><code class="language-sql">DELETE FROM Person
WHERE Id = 3;</code></pre><h2 id="inner-join">INNER JOIN</h2><p><code>JOIN</code> (junção, em inglês), também chamado de <em>inner join</em> (junção interna, em inglês), seleciona registros que têm valores correspondentes em duas tabelas.‌ &nbsp;</p><pre><code class="language-sql">SELECT * FROM A x JOIN B y ON y.aId = x.Id</code></pre><h2 id="left-join">LEFT JOIN</h2><p>A <code>LEFT JOIN</code> (junção à esquerda, em inglês) retorna todas as linhas da tabela da esquerda e as linhas correspondentes da tabela da direita. As linhas na tabela da esquerda serão retornadas mesmo que não haja correspondência na tabela da direita. As linhas da tabela à esquerda sem correspondência na tabela à direita terão os valores da tabela à direita <code>null</code>.‌</p><pre><code class="language-sql">SELECT * FROM A x LEFT JOIN B y ON y.aId = x.Id</code></pre><h2 id="-right-join">‌RIGHT JOIN</h2><p>A <code>RIGHT JOIN</code> (junção à direita, em inglês) retorna todas as linhas da tabela da direita e as linhas correspondentes da tabela da esquerda. Ao contrário de uma junção à esquerda, isso retornará todas as linhas da tabela à direita, mesmo quando não houver correspondência na tabela à esquerda. As linhas na tabela à direita que não têm correspondência na tabela à esquerda terão valores <code>null</code> para as colunas da tabela à esquerda.‌ </p><pre><code class="language-sql">SELECT * FROM A x RIGHT JOIN B y ON y.aId = x.Id</code></pre><h2 id="full-outer-join">FULL OUTER JOIN</h2><p>A <code>FULL OUTER JOIN</code> (junção externa completa, em inglês) retorna todas as linhas para as quais haja uma correspondência em qualquer uma das tabelas. Portanto, se houver linhas na tabela da esquerda que não tenham correspondência na tabela da direita, elas serão incluídas. Além disso, se houver linhas na tabela à direita que não tenham correspondência na tabela à esquerda, elas também o serão.‌ </p><pre><code class="language-sql">SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
FULL OUTER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName</code></pre><h2 id="insert">INSERT</h2><p><code>INSERT</code> (inserir, em inglês) é uma maneira de inserir dados em uma tabela.‌ </p><pre><code class="language-sql">INSERT INTO nome_da_tabela (coluna_1, coluna_2, coluna_3) 
VALUES (valor_1, 'valor_2', valor_3);</code></pre><h2 id="like">LIKE</h2><p><code>LIKE</code> &nbsp;(como, em inglês - comparar com "<em>as"</em> acima) é usado em uma instrução com <code>WHERE</code> ou <code>HAVING</code>(como parte de <code>GROUP BY</code>) para limitar as linhas selecionadas aos itens quando uma coluna possui um determinado padrão de caracteres contido nela.</p><p>Este SQL selecionará os alunos que tem <code>FullName</code> começando com "Monique" ou que terminam com "Greene".‌ &nbsp; &nbsp;</p><pre><code class="language-sql">SELECT studentID, FullName, sat_score, rcd_updated
FROM student 
WHERE 
    FullName LIKE 'Monique%' OR 
    FullName LIKE '%Greene'; </code></pre><pre><code class="language-text">+-----------+---------------+-----------+---------------------+
| studentID | FullName      | sat_score | rcd_updated         |
+-----------+---------------+-----------+---------------------+
|         1 | Monique Davis |       400 | 2017-08-16 15:34:50 |
|         5 | Alvin Greene  |      1200 | 2017-08-16 15:34:50 |
+-----------+---------------+-----------+---------------------+
2 rows in set (0.00 sec)</code></pre><p>Você pode colocar <code>NOT</code> antes de <code>LIKE</code> para excluir as linhas com o padrão de string em vez de selecioná-las. Esse SQL exclui registros que contenham "encer Pauti" e "Ted" na coluna FullName.‌ &nbsp; &nbsp;</p><pre><code class="language-sql">SELECT studentID, FullName, sat_score, rcd_updated
FROM student 
WHERE FullName NOT LIKE '%encer Pauti%' AND FullName NOT LIKE '%"Ted"%';</code></pre><pre><code class="language-text">+-----------+----------------------+-----------+---------------------+
| studentID | FullName             | sat_score | rcd_updated         |
+-----------+----------------------+-----------+---------------------+
|         1 | Monique Davis        |       400 | 2017-08-16 15:34:50 |
|         2 | Teri Gutierrez       |       800 | 2017-08-16 15:34:50 |
|         4 | Louis Ramsey         |      1200 | 2017-08-16 15:34:50 |
|         5 | Alvin Greene         |      1200 | 2017-08-16 15:34:50 |
|         6 | Sophie Freeman       |      1200 | 2017-08-16 15:34:50 |
|         8 | Donald D. Chamberlin |      2400 | 2017-08-16 15:35:33 |
|         9 | Raymond F. Boyce     |      2400 | 2017-08-16 15:35:33 |
+-----------+----------------------+-----------+---------------------+
7 rows in set (0.00 sec)</code></pre> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Requisitando módulos no Node.js: tudo o que você precisa saber ]]>
                </title>
                <description>
                    <![CDATA[ > ‌Atualização: este artigo agora faz parte do livro do autor, "Node.js Beyond The Basics". Leia a versão atualizada deste conteúdo (em inglês) e mais sobre o Node em jcomplete.com/node-beyond-basics [https://translate.google.com/website?sl=en&tl=pt&hl=pt-BR&client=webapp&u=https://jscomplete.com/g/node-modules]  . O Node usa dois módulos principais para gerenciar as dependências de módulos:  * O módulo require, ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/requisitando-modulos-no-node-js-tudo-o-que-voce-precisa-saber/</link>
                <guid isPermaLink="false">620576ddcfef2204db7eda66</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Fernando Mota Freitas ]]>
                </dc:creator>
                <pubDate>Sat, 19 Feb 2022 22:34:25 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/artigo2-node-require-modules-1-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/requiring-modules-in-node-js-everything-you-need-to-know-e7fbd119be8/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Requiring modules in Node.js: Everything you need to know</a>
      </p><blockquote>‌<strong>Atualização:</strong> este artigo agora faz parte do livro do autor, "Node.js Beyond The Basics". Leia a versão atualizada deste conteúdo (em inglês) e mais sobre o Node em <a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://jscomplete.com/g/node-modules" rel="noopener"><strong>jcomplete.com/node-beyond-basics</strong></a> .</blockquote><p>O Node usa dois módulos principais para gerenciar as dependências de módulos:</p><ul><li>O módulo <code>require</code>, que parece estar disponível no escopo global — não há necessidade de <code>require('require')</code>.</li><li>O módulo <code>module</code>, que também parece estar disponível no escopo global — não há necessidade de <code>require('module')</code>.</li></ul><p>Você pode pensar no módulo <code>require</code> como um comando e no módulo <code>module</code> como um organizador de todos os módulos necessários.</p><p>Requisitar um módulo no Node não é um conceito tão complicado.</p><pre><code class="language-js">const config = require('/path/to/file');</code></pre><p>‌O objeto principal exportado pelo módulo <code>require</code> é uma função (conforme usado no exemplo acima). Quando o Node invoca essa função <code>require()</code> com um caminho de arquivo local como único argumento da função, o Node passa pela seguinte sequência de etapas:</p><ul><li><strong>Resolver</strong>: para encontrar o caminho absoluto do arquivo.</li><li><strong>Carregar</strong>: para determinar o tipo de conteúdo do arquivo.</li><li><strong>Envolver (Wrapping)</strong>: para dar ao arquivo seu escopo privado. Isso é o que torna os objetos locais <code>require</code> e <code>module</code> para cada arquivo que precisamos.</li><li><strong>Avaliar</strong>: isso é o que a VM eventualmente faz com o código carregado.</li><li><strong>Colocar em cache</strong>: para que, quando precisarmos desse arquivo novamente, não passemos por todas as etapas outra vez.</li></ul><p>Neste artigo, tentarei explicar com exemplos esses diferentes estágios e como eles afetam a maneira como escrevemos módulos no Node.</p><p>Deixe-me primeiro criar um diretório para hospedar todos os exemplos usando meu terminal:</p><pre><code class="language-bash">mkdir ~/learn-node &amp;&amp; cd ~/learn-node</code></pre><p>‌Todos os comandos no restante deste artigo serão executados de dentro do diretório <code>~/learn-node</code>.</p><h4 id="resolvendo-um-caminho-local">Resolvendo um caminho local</h4><p>Quero apresentá-lo ao objeto <code>module</code>. Você pode verificá-lo em uma sessão simples do REPL:</p><pre><code class="language-bash">~/learn-node $ node
&gt; module
Module {
  id: '&lt;repl&gt;',
  exports: {},
  parent: undefined,
  filename: null,
  loaded: false,
  children: [],
  paths: [ ... ] }</code></pre><p>‌Cada objeto de módulo recebe uma propriedade <code>id</code> para identificá-lo. Este <code>id</code> é geralmente o caminho completo para o arquivo, mas, em uma sessão REPL, ele é simplesmente <code>&lt;repl&gt;.</code> &nbsp;</p><p>Os módulos do Node têm uma relação de um-para-um com arquivos no sistema de arquivos. Requisitamos um módulo carregando o conteúdo de um arquivo na memória.</p><p>No entanto, como o Node permite muitas maneiras de requisitar um arquivo (por exemplo, com um caminho relativo ou um caminho pré-configurado), antes de podermos carregar o conteúdo de um arquivo na memória, precisamos encontrar a localização absoluta desse arquivo.</p><p>Quando requisitamos um módulo <code>'find-me'</code>, sem especificar um caminho:</p><pre><code class="language-js">require('find-me');</code></pre><p>O Node procurará <code>find-me.js</code> em todos os caminhos especificados por <code>module.paths</code>— em ordem.</p><pre><code class="language-bash">~/learn-node $ node
&gt; module.paths
[ '/Users/samer/learn-node/repl/node_modules',
  '/Users/samer/learn-node/node_modules',
  '/Users/samer/node_modules',
  '/Users/node_modules',
  '/node_modules',
  '/Users/samer/.node_modules',
  '/Users/samer/.node_libraries',
  '/usr/local/Cellar/node/7.7.1/lib/node' ]</code></pre><p>A lista de caminhos é basicamente uma lista de diretórios <code>node_modules</code> que se encontra em cada diretório, começando do diretório atual e chegando até o diretório raiz. Ela também inclui alguns diretórios legados, cujo uso não é recomendado.</p><p>Se o Node não puder encontrar <code>find-me.js</code> em nenhum desses caminhos, ele lançará um erro dizendo que o módulo não foi encontrado.</p><pre><code class="language-bash">~/learn-node $ node
&gt; require('find-me')
Error: Cannot find module 'find-me'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at repl:1:1
    at ContextifyScript.Script.runInThisContext (vm.js:23:33)
    at REPLServer.defaultEval (repl.js:336:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.onLine (repl.js:533:10)</code></pre><p>Se você agora criar um diretório local <code>node_modules</code> e colocar um <code>find-me.js</code> lá, a linha <code>require('find-me')</code> o encontrará.</p><pre><code class="language-bash">~/learn-node $ mkdir node_modules 

~/learn-node $ echo "console.log('I am not lost');" &gt; node_modules/find-me.js

~/learn-node $ node
&gt; require('find-me');
I am not lost
{}
&gt;</code></pre><p>‌Se existir outro arquivo <code>find-me.js</code> em qualquer um dos outros caminhos – por exemplo, se tivermos um diretório <code>node_modules</code> no diretório inicial e se tivermos um arquivo <code>find-me.js</code> diferente lá:</p><pre><code class="language-bash">$ mkdir ~/node_modules
$ echo "console.log('I am the root of all problems');" &gt; ~/node_modules/find-me.js</code></pre><p>Quando usamos <code>require('find-me')</code> dentro do diretório <code>learn-node</code>, que tem seu próprio <code>node_modules/find-me.js</code>, o arquivo <code>find-me.js</code> no diretório inicial não será carregado:</p><pre><code class="language-bash">~/learn-node $ node
&gt; require('find-me')
I am not lost
{}
&gt;</code></pre><p>‌Se removermos o diretório local <code>node_modules</code> de <code>~/learn-node</code> e se tentarmos solicitar <code>find-me</code> mais uma vez, o arquivo no <code>node_modules</code> diretório home será usado:</p><pre><code class="language-bash">~/learn-node $ rm -r node_modules/
~/learn-node $ node
&gt; require('find-me')
I am the root of all problems
{}
&gt;</code></pre><h4 id="solicitando-uma-pasta">Solicitando uma pasta</h4><p>Os módulos não precisam ser arquivos. Também podemos criar uma pasta <code>find-me</code> em <code>node_modules</code> e colocar um arquivo <code>index.js</code> lá. A linha <code>require('find-me')</code> usará o arquivo <code>index.js</code> dessa pasta:</p><pre><code class="language-bash">~/learn-node $ mkdir -p node_modules/find-me

~/learn-node $ echo "console.log('Found again.');" &gt; node_modules/find-me/index.js

~/learn-node $ node
&gt; require('find-me');
Found again.
{}
&gt;</code></pre><p>Observe como ele ignorou o caminho do diretório inicial <code>node_modules</code> novamente, pois agora temos um local.</p><p>Um arquivo <code>index.js</code> será usado por padrão quando precisarmos de uma pasta, mas podemos controlar com qual nome de arquivo começar na pasta usando a propriedade <code>main</code> no <code>package.json</code>. Por exemplo, para fazer com que a linha <code>require('find-me')</code> resolva para um arquivo diferente na pasta <code>find-me</code>, tudo o que precisamos fazer é adicionar um arquivo <code>package.json</code> e especificar qual arquivo deve ser usado para resolver esta pasta:</p><pre><code class="language-bash">~/learn-node $ echo "console.log('I rule');" &gt; node_modules/find-me/start.js

~/learn-node $ echo '{ "name": "find-me-folder", "main": "start.js" }' &gt; node_modules/find-me/package.json

~/learn-node $ node
&gt; require('find-me');
I rule
{}
&gt;</code></pre><p>‌require.resolve</p><p>Se você quiser apenas resolver o módulo e não executá-lo, você pode usar a função <code>require.resolve</code>. Ela se comporta exatamente da mesma forma que a função principal <code>require</code>, mas não carrega o arquivo. Ela ainda lançará um erro se o arquivo não existir e retornará o caminho completo para o arquivo quando encontrado.</p><pre><code class="language-bash">&gt; require.resolve('find-me');
'/Users/samer/learn-node/node_modules/find-me/start.js'
&gt; require.resolve('not-there');
Error: Cannot find module 'not-there'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.resolve (internal/module.js:27:19)
    at repl:1:9
    at ContextifyScript.Script.runInThisContext (vm.js:23:33)
    at REPLServer.defaultEval (repl.js:336:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.onLine (repl.js:533:10)
    at emitOne (events.js:101:20)
    at REPLServer.emit (events.js:191:7)
&gt;</code></pre><p>Isso pode ser usado, por exemplo, para verificar se um pacote opcional está instalado ou não e só usá-lo quando estiver disponível.</p><h4 id="caminhos-relativos-e-absolutos">Caminhos relativos e absolutos</h4><p>Além de resolver módulos de dentro dos diretórios <code>node_modules</code>, também podemos colocar o módulo em qualquer lugar que quisermos e requisitá-lo com os caminhos relativos ( <code>./</code>e <code>../</code>) ou com caminhos absolutos começando com <code>/</code>.</p><p>Se, por exemplo, o arquivo <code>find-me.js</code> estiver em uma pasta <code>lib</code> em vez da pasta <code>node_modules</code>, podemos requisitá-lo com:</p><pre><code class="language-js">require('./lib/find-me');</code></pre><h4 id="rela-o-pai-filho-entre-arquivos">Relação pai-filho entre arquivos</h4><p>Crie um arquivo <code>lib/util.js</code> e adicione uma linha <code>console.log</code> para identificá-lo. Além disso, faça um <code>console.log</code> com o próprio objeto <code>module</code>:</p><pre><code class="language-bash">~/learn-node $ mkdir lib
~/learn-node $ echo "console.log('In util', module);" &gt; lib/util.js</code></pre><p>‌Faça o mesmo para um arquivo <code>index.js</code>, que executaremos com o comando node. Faça este arquivo <code>index.js</code> requisitar <code>lib/util.js</code>:</p><pre><code class="language-bash">~/learn-node $ echo "console.log('In index', module); require('./lib/util');" &gt; index.js</code></pre><p>‌Agora execute o arquivo<code>index.js</code> com o node:</p><pre><code class="language-bash">~/learn-node $ node index.js
In index Module {
  id: '.',
  exports: {},
  parent: null,
  filename: '/Users/samer/learn-node/index.js',
  loaded: false,
  children: [],
  paths: [ ... ] }
In util Module {
  id: '/Users/samer/learn-node/lib/util.js',
  exports: {},
  parent:
   Module {
     id: '.',
     exports: {},
     parent: null,
     filename: '/Users/samer/learn-node/index.js',
     loaded: false,
     children: [ [Circular] ],
     paths: [...] },
  filename: '/Users/samer/learn-node/lib/util.js',
  loaded: false,
  children: [],
  paths: [...] }</code></pre><p>‌Observe como o módulo <code>index</code> principal <code>(id: '.')</code>agora está listado como pai do módulo <code>lib/util</code>. No entanto, o módulo <code>lib/util</code> não foi listado como filho do módulo <code>index</code>. Em vez disso, temos o valor <code>[Circular]</code> lá porque esta é uma referência circular. Se o Node imprimir o objeto <code>lib/util</code> do módulo, ele entrará em um loop infinito. É por isso que ele simplesmente substitui a referência a <code>lib/util</code> por <code>[Circular]</code>.</p><p>Mais importante agora, o que acontece se o módulo <code>lib/util</code> requisitar o módulo <code>index</code> principal? É aqui que entramos no que é conhecido como dependência modular circular, que é permitida no Node.</p><p>Para entender melhor, vamos primeiro entender alguns outros conceitos sobre o objeto módulo.</p><h4 id="exports-module-exports-e-carregamento-s-ncrono-de-m-dulos">exports, module.exports e carregamento síncrono de módulos</h4><p>Em qualquer módulo, as exportações são um objeto especial. Se você notou acima, toda vez que imprimimos um objeto de módulo, &nbsp;até agora, ele tinha uma propriedade de exportação que era um objeto vazio. Podemos adicionar qualquer atributo a este objeto especial de exportação. Por exemplo, vamos exportar um atributo id para <code>index.js</code> e <code>lib/util.js</code>:</p><pre><code class="language-js">// Adicione a linha a seguir na parte superior do lib/util.js
exports.id = 'lib/util';

// Adicione a linha a seguir na parte superior do index.js
exports.id = 'index';</code></pre><p>‌Quando executarmos <code>index.js</code>, veremos esses atributos gerenciados no objeto <code>module</code> de cada arquivo:</p><pre><code class="language-bash">~/learn-node $ node index.js
In index Module {
  id: '.',
  exports: { id: 'index' },
  loaded: false,
  ... }
In util Module {
  id: '/Users/samer/learn-node/lib/util.js',
  exports: { id: 'lib/util' },
  parent:
   Module {
     id: '.',
     exports: { id: 'index' },
     loaded: false,
     ... },
  loaded: false,
  ... }</code></pre><p>Eu removi alguns atributos na saída acima para mantê-la pequena, mas observe como o objeto <code>exports</code> agora tem os atributos que definimos em cada módulo. Você pode colocar quantos atributos quiser nesse objeto de exportação e, na verdade, pode alterar todo o objeto para outra coisa. Por exemplo, para alterar o objeto de exportação para que seja uma função em vez de um objeto, fazemos o seguinte:</p><pre><code class="language-js">// Adicione a linha a seguir no index.js antes do console.log

module.exports = function() {};</code></pre><p>Ao executar <code>index.js</code> agora, você verá como o objeto <code>exports</code> é uma função:</p><pre><code class="language-bash">~/learn-node $ node index.js
In index Module {
  id: '.',
  exports: [Function],
  loaded: false,
  ... }</code></pre><p>‌Observe como não fizemos <code>exports = function() {}</code> para transformar o objeto <code>exports</code> em uma função. Na verdade, não podemos fazer isso porque a variável <code>exports</code> dentro de cada módulo é apenas uma referência à <code>module.exports</code> que gerencia as propriedades exportadas. Quando atribuímos novamente a variável <code>exports</code>, essa referência é perdida e estaríamos introduzindo uma nova variável em vez de alterar o objeto <code>module.exports</code>.</p><p>O objeto <code>module.exports</code> em cada módulo é o que a função <code>require</code> retorna quando precisamos desse módulo. Por exemplo, altere a linha <code>require('./lib/util')</code> no <code>index.js</code> para:</p><pre><code class="language-js">const UTIL = require('./lib/util');

console.log('UTIL:', UTIL);</code></pre><p>‌O código acima vai capturar as propriedades exportadas <code>lib/util</code> para a constante <code>UTIL</code>. Quando executarmos <code>index.js</code> agora, a última linha produzirá:</p><pre><code class="language-bash">UTIL: { id: 'lib/util' }</code></pre><p>Vamos também falar sobre o atributo <code>loaded</code> em cada módulo. Até agora, toda vez que imprimimos um objeto de módulo, vimos um atributo <code>loaded</code> nesse objeto com um valor de <code>false</code>.</p><p>O módulo <code>module</code> usa o atributo <code>loaded</code> para rastrear quais módulos foram carregados (valor <em>true</em>) e quais módulos ainda estão sendo carregados (valor <em>false</em>). Podemos, por exemplo, ver o módulo <code>index.js</code> totalmente carregado se imprimirmos seu objeto <code>module</code> no próximo ciclo do loop de eventos usando uma chamada a <code>setImmediate</code>:</p><pre><code>// No index.js
setImmediate(() =&gt; {
  console.log('The index.js module object is now loaded!', module)
});</code></pre><p>‌A saída disso seria:</p><pre><code class="language-bash">The index.js module object is now loaded! Module {
  id: '.',
  exports: [Function],
  parent: null,
  filename: '/Users/samer/learn-node/index.js',
  loaded: true,
  children:
   [ Module {
       id: '/Users/samer/learn-node/lib/util.js',
       exports: [Object],
       parent: [Circular],
       filename: '/Users/samer/learn-node/lib/util.js',
       loaded: true,
       children: [],
       paths: [Object] } ],
  paths:
   [ '/Users/samer/learn-node/node_modules',
     '/Users/samer/node_modules',
     '/Users/node_modules',
     '/node_modules' ] }</code></pre><p>Observe como neste <code>console.log</code> posterior <code>lib/util.js</code> e <code>index.js</code> estão totalmente carregados.</p><p>O objeto <code>exports</code> fica completo quando o Node termina de carregar o módulo (e o rotula assim). Todo o processo de solicitação/carregamento de um módulo é <em>síncrono. </em>É por isso que conseguimos ver os módulos totalmente carregados após um ciclo do loop de eventos.</p><p>Isso também significa que não podemos alterar o objeto <code>exports</code> de forma assíncrona. Não podemos, por exemplo, fazer o seguinte em nenhum módulo:</p><pre><code class="language-js">fs.readFile('/etc/passwd', (err, data) =&gt; {
  if (err) throw err;
  
  exports.data = data; // Will not work.
});</code></pre><h4 id="depend-ncia-do-m-dulo-circular">Dependência do módulo circular</h4><p>Vamos agora tentar responder a uma questão importante sobre dependência circular no Node: o que acontece quando o módulo 1 requer o módulo 2 e o módulo 2 requer o módulo 1?</p><p>Para descobrir, vamos criar os dois arquivos a seguir em <code>lib/</code>, <code>module1.js</code> e <code>module2.js</code>, e fazer com que eles solicitem um ao outro:</p><pre><code class="language-js">// lib/module1.js

exports.a = 1;

require('./module2');

exports.b = 2;
exports.c = 3;

// lib/module2.js

const Module1 = require('./module1');
console.log('Module1 is partially loaded here', Module1);</code></pre><p>Quando rodamos <code>module1.js</code> vemos o seguinte:</p><pre><code class="language-bash">~/learn-node $ node lib/module1.js
Module1 is partially loaded here { a: 1 }</code></pre><p>‌Requisitamos <code>module2</code> antes que <code>module1</code> fosse totalmente carregado e, como <code>module2</code> solicitou <code>module1</code> enquanto não estava totalmente carregado, o que obtemos do objeto <code>exports</code> nesse ponto são todas as propriedades exportadas antes da dependência circular. Apenas a propriedade <code>a</code> foi informada, pois tanto <code>b</code> quanto <code>c</code> foram exportadas após <code>module2</code> ter solicitado e mostrado o resultado de <code>module1</code>.</p><p>O Node mantém isso muito simples. Durante o carregamento de um módulo, ele constrói o objeto <code>exports</code>. Você pode requisitar o módulo antes de terminar de carregar e obterá apenas um objeto de exportação parcial com o que foi definido até agora.</p><h4 id="complementos-json-e-c-c-">Complementos JSON e C/C++</h4><p>Podemos requisitar nativamente arquivos JSON e arquivos de complemento C++ com a função require. Você nem precisa especificar uma extensão de arquivo para fazer isso.</p><p>Se uma extensão de arquivo não foi especificada, a primeira coisa que o Node tentará resolver é um arquivo <code>.js</code>. Se não encontrar um arquivo <code>.js</code>, ele tentará achar um arquivo <code>.json</code> e analisará o arquivo <code>.json</code> se o encontrar como um arquivo de texto JSON. Depois disso, ele tentará encontrar um arquivo <code>.node</code> binário. No entanto, para remover a ambiguidade, você provavelmente deve especificar uma extensão de arquivo ao requisitar algo além de arquivos <code>.js</code>.</p><p>A exigência de arquivos JSON é útil se, por exemplo, tudo o que você precisa para gerenciar nesse arquivo são alguns valores de configuração estática ou alguns valores que você lê periodicamente de uma fonte externa. Por exemplo, se tivéssemos o seguinte arquivo <code>config.json</code>:</p><pre><code class="language-json">{
  "host": "localhost",
  "port": 8080
}</code></pre><p>Podemos solicitá-lo diretamente assim:</p><pre><code>const { host, port } = require('./config');

console.log(`Server will run at http://${host}:${port}`);</code></pre><p>‌A execução do código acima terá esta saída:</p><pre><code class="language-bash">Server will run at http://localhost:8080</code></pre><p>‌Se o Node não encontrar um arquivo <code>.js</code> ou um arquivo <code>.json</code>, ele procurará um arquivo <code>.node</code> e interpretará o arquivo como um módulo complementar compilado.</p><p>O site de documentação do Node tem um <a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://nodejs.org/api/addons.html%23addons_hello_world" rel="noopener">arquivo complementar de exemplo</a> escrito em C++. É um módulo simples que expõe uma função <code>hello()</code> e a função hello gera “world”.</p><p>Você pode usar o pacote <code>node-gyp</code> para compilar e criar o arquivo <code>.cc</code> em um arquivo <code>.node</code>. Você só precisa configurar um arquivo <a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://nodejs.org/api/addons.html%23addons_building" rel="noopener">binding.gyp</a> para dizer ao <code>node-gyp</code> o que fazer.</p><p>Depois de ter o arquivo <code>addon.node</code> (ou qualquer nome que você especificar em <code>binding.gyp</code>), você poderá requisitá-lo nativamente como qualquer outro módulo:</p><pre><code class="language-js">const addon = require('./addon');

console.log(addon.hello());</code></pre><p>‌Na verdade, podemos ver o suporte das três extensões olhando para <code>require.extensions</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/D3NuN7cetXAjYpHfqBGribFo-ex0fj-AvuDA.png" class="kg-image" alt="D3NuN7cetXAjYpHfqBGribFo-ex0fj-AvuDA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/D3NuN7cetXAjYpHfqBGribFo-ex0fj-AvuDA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/D3NuN7cetXAjYpHfqBGribFo-ex0fj-AvuDA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="443" loading="lazy"></figure><p>‌ ‌Observando as funções de cada extensão, você pode ver claramente o que o Node fará com cada uma. Ele usa <code>module._compile</code> para arquivos <code>.js</code>, <code>JSON.parse</code> para arquivos <code>.json</code> e <code>process.dlopen</code> para arquivos <code>.node</code>.</p><h4 id="todo-o-c-digo-que-voc-escreve-no-node-ser-envolvido-por-fun-es">Todo o código que você escreve no Node será envolvido por funções</h4><p>O encapsulamento de módulos do Node geralmente é mal compreendido. Para entendê-lo, deixe-me lembrá-lo sobre a relação <code>exports</code>/<code>module.exports</code>.</p><p>Podemos usar o objeto <code>exports</code> para exportar propriedades, mas não podemos substituir o objeto <code>exports</code> diretamente, porque é apenas uma referência a <code>module.exports</code>.</p><pre><code class="language-js">exports.id = 42; // Isto está ok.

exports = { id: 42 }; // Isso não funcionará.

module.exports = { id: 42 }; // Isto está ok.</code></pre><p>‌Como exatamente esse objeto <code>exports</code>, que parece ser global para cada módulo, é definido como uma referência no objeto <code>module</code>?</p><p>Deixe-me fazer mais uma pergunta antes de explicar o processo de encapsulamento do Node.</p><p>Em um navegador, quando declaramos uma variável em um script como este:</p><pre><code>var answer = 42;</code></pre><p>‌Essa variável <code>answer</code> estará disponível globalmente em todos os scripts após o script que a definiu.</p><p>Este não é o caso do Node. Quando definimos uma variável em um módulo, os outros módulos do programa não terão acesso a essa variável. Então, como as variáveis ​​no Node têm escopo mágico?</p><p>A resposta é simples. Antes de compilar um módulo, o Node envolve o código do módulo em uma função, que podemos inspecionar usando a propriedade <code>wrapper</code> (que poderia ser traduzida como "invólucro", ou "envelope") do módulo <code>module</code>.</p><pre><code class="language-bash">~ $ node
&gt; require('module').wrapper
[ '(function (exports, require, module, __filename, __dirname) { ',
  '\n});' ]
&gt;</code></pre><p>O Node não executa nenhum código que você escreve em um arquivo diretamente. Ele executa esta função wrapper que terá seu código em seu corpo. Isso é o que mantém as variáveis ​​de nível superior definidas em qualquer módulo com escopo para esse módulo.</p><p>Esta função wrapper tem 5 argumentos: <code>exports</code>, <code>require</code>, <code>module</code>, <code>__filename</code> e <code>__dirname</code>. É isso que os faz parecerem globais quando na verdade são específicos para cada módulo.</p><p>Todos esses argumentos obtêm seus valores quando o Node executa a função wrapper. <code>exports</code> é definida como uma referência a <code>module.exports</code> antes disso. <code>require</code> e <code>module</code> são específicas para a função a ser executada, enquanto as variáveis <code>__filename</code>/<code>__dirname</code> conterão o nome de arquivo absoluto do módulo encapsulado e o caminho do diretório.</p><p>Você pode ver esse encapsulamento em ação se executar um script com um problema em sua primeira linha:</p><pre><code class="language-bash">~/learn-node $ echo "euaohseu" &gt; bad.js

~/learn-node $ node bad.js
~/bad.js:1
(function (exports, require, module, __filename, __dirname) { euaohseu
                                                              ^
ReferenceError: euaohseu is not defined</code></pre><p>‌Observe como a primeira linha do script, conforme relatado acima, era a função wrapper, não a referência incorreta.</p><p>Além disso, como cada módulo é envolvido em uma função, podemos acessar os argumentos dessa função com a palavra-chave <code>arguments</code>:</p><pre><code class="language-bash">~/learn-node $ echo "console.log(arguments)" &gt; index.js

~/learn-node $ node index.js
{ '0': {},
  '1':
   { [Function: require]
     resolve: [Function: resolve],
     main:
      Module {
        id: '.',
        exports: {},
        parent: null,
        filename: '/Users/samer/index.js',
        loaded: false,
        children: [],
        paths: [Object] },
     extensions: { ... },
     cache: { '/Users/samer/index.js': [Object] } },
  '2':
   Module {
     id: '.',
     exports: {},
     parent: null,
     filename: '/Users/samer/index.js',
     loaded: false,
     children: [],
     paths: [ ... ] },
  '3': '/Users/samer/index.js',
  '4': '/Users/samer' }</code></pre><p>‌O primeiro argumento é o objeto <code>exports</code>, que começa vazio. Então temos os objetos <code>require</code>/<code>module</code>, que são instâncias associadas ao arquivo <code>index.js</code> em execução. Não são variáveis ​​globais. Os últimos 2 argumentos são o caminho do arquivo e o caminho do diretório.</p><p>O valor de retorno da função de encapsulamento é <code>module.exports</code>. Dentro da função encapsulada, podemos usar o objeto <code>exports</code> para alterar as propriedades de <code>module.exports</code>, mas não podemos reatribuir as próprias exportações porque é apenas uma referência.</p><p>O que acontece equivale aproximadamente a:</p><pre><code class="language-js">function (require, module, __filename, __dirname) {
  let exports = module.exports;
  
  // Seu código aqui...
  
  return module.exports;
}</code></pre><p>Se alterarmos o objeto <code>exports</code> inteiro, ele não será mais uma referência a <code>module.exports</code>. É assim que os objetos de referência do JavaScript funcionam em todos os lugares, não apenas neste contexto.</p><h4 id="o-objeto-necess-rio">O objeto necessário</h4><p>Não há nada de especial em <code>require</code>. É um objeto que atua principalmente como uma função que recebe um nome de módulo ou caminho e retorna o objeto <code>module.exports</code>. Podemos simplesmente substituir o objeto <code>require</code> com nossa própria lógica, se quisermos.</p><p>Por exemplo, talvez para fins de teste, queremos que cada chamada de <code>require</code> seja simulada por padrão e apenas retorne um objeto falso em vez do objeto de exportação de módulo necessário. Essa simples reatribuição de require resolverá o problema:</p><pre><code class="language-js">require = function() {

  return { mocked: true };
  
}</code></pre><p>Depois de fazer a reatribuição de <code>require</code>, cada chamada a <code>require('something')</code> no script retornará apenas o objeto simulado.</p><p>O objeto require também possui propriedades próprias. Vimos a propriedade <code>resolve</code>, que é uma função que executa apenas a etapa de resolução do processo require. Também vimos <code>require.extensions</code> acima.</p><p>Há também <code>require.main</code>, que pode ser útil para determinar se o script está sendo necessário ou executado diretamente.</p><p>Digamos, por exemplo, que temos esta função simples <code>printInFrame</code> em <code>print-in-frame.js</code>:</p><pre><code class="language-js">// Em print-in-frame.js

const printInFrame = (size, header) =&gt; {
  console.log('*'.repeat(size));
  console.log(header);
  console.log('*'.repeat(size));
};</code></pre><p>A função recebe um argumento numérico <code>size</code> e um argumento string <code>header</code> e imprime esse cabeçalho em um quadro de estrelas controlado pelo tamanho que especificamos.</p><p>Queremos usar este arquivo de duas maneiras:</p><ol><li>A partir da linha de comando diretamente, assim:</li></ol><pre><code class="language-bash">~/learn-node $ node print-in-frame 8 Hello</code></pre><p>‌Passando 8 e Hello como argumentos de linha de comando para imprimir "Hello" em um quadro de 8 estrelas.</p><p>2. Com <code>require</code>. Supondo que o módulo necessário exportará a função <code>printInFrame</code>, podemos simplesmente chamá-la:</p><pre><code>const print = require('./print-in-frame');

print(5, 'Hey');</code></pre><p>Para imprimir o cabeçalho "Hey" em um quadro de 5 estrelas.</p><p>São dois usos diferentes. Precisamos de uma maneira de determinar se o arquivo está sendo executado como um script autônomo ou se está sendo requisitado por outros scripts.</p><p>É aqui que podemos usar esta instrução if simples:</p><pre><code class="language-js">if (require.main === module) {
  // O arquivo está sendo executado diretamente (sem o require)
}</code></pre><p>Assim, podemos usar esta condição para satisfazer os requisitos de uso acima invocando a função printInFrame de forma diferente:</p><pre><code class="language-js">// Em print-in-frame.js

const printInFrame = (size, header) =&gt; {
  console.log('*'.repeat(size));
  console.log(header);
  console.log('*'.repeat(size));
};

if (require.main === module) {
  printInFrame(process.argv[2], process.argv[3]);
} else {
  module.exports = printInFrame;
}</code></pre><p>‌Quando o arquivo não está sendo requerido, apenas chamamos a função <code>printInFrame</code> com elementos <code>process.argv</code>. Caso contrário, apenas alteramos o <code>module.exports</code> para ser a própria função <code>printInFrame</code>.</p><h4 id="todos-os-m-dulos-ser-o-armazenados-em-cache">Todos os módulos serão armazenados em cache</h4><p>O cache é importante para entender. Deixe-me usar um exemplo simples para demonstrá-lo.</p><p>Digamos que você tenha o seguinte arquivo <code>ascii-art.js</code> que imprime um cabeçalho:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/RbgFBaBdZszHFKEcmsyE8mMW7udDG4NdYofy.png" class="kg-image" alt="RbgFBaBdZszHFKEcmsyE8mMW7udDG4NdYofy" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/RbgFBaBdZszHFKEcmsyE8mMW7udDG4NdYofy.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/RbgFBaBdZszHFKEcmsyE8mMW7udDG4NdYofy.png 800w" sizes="(min-width: 720px) 720px" width="800" height="220" loading="lazy"></figure><p>‌Queremos exibir esse cabeçalho toda vez que <em>precisarmos</em> do arquivo. Então, quando requisitamos o arquivo duas vezes, queremos que o cabeçalho apareça duas vezes.</p><pre><code class="language-js">require('./ascii-art') // mostrará o cabeçalho.
require('./ascii-art') // não mostrará o cabeçalho.</code></pre><p>‌O segundo require não mostrará o cabeçalho devido ao cache dos módulos. O Node armazena em cache a primeira chamada e não carrega o arquivo na segunda chamada.</p><p>Podemos ver esse cache imprimindo <code>require.cache</code> após o primeiro require. O registro de cache é simplesmente um objeto que possui uma propriedade para cada módulo necessário. Esses valores de propriedades são os objetos <code>module</code> usados ​​para cada módulo. Podemos simplesmente excluir uma propriedade desse objeto <code>require.cache</code> para invalidar esse cache. Se fizermos isso, o Node recarregará o módulo para recarregá-lo em cache.</p><p>No entanto, esta não é a solução mais eficiente para este caso. A solução simples é envolver a linha de log <code>ascii-art.js</code> com uma função e exportar essa função. Dessa forma, quando solicitamos o arquivo <code>ascii-art.js</code>, obtemos uma função que podemos executar para invocar a linha de log todas as vezes:</p><pre><code class="language-js">require('./ascii-art')() // mostrará o cabeçalho.
require('./ascii-art')() // também mostrará o cabeçalho.</code></pre><p>Isso era o que eu tinha para falar sobre este tópico. Obrigado pela leitura e até a próxima!</p><p>Aprendendo React ou Node? Confira os livros do autor (em inglês):</p><ul><li><a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=http://amzn.to/2peYJZj" rel="noopener">Learn React.js by Building Games</a></li><li><a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=http://amzn.to/2FYfYru" rel="noopener">Node.js Beyond the Basics</a></li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ O processo de inicialização do Linux - 6 etapas descritas em detalhes ]]>
                </title>
                <description>
                    <![CDATA[ Um sistema operacional (SO) é o software de baixo nível que gerencia recursos, controla periféricos e fornece serviços básicos para outros softwares. No Linux, existem 6 estágios distintos no processo de inicialização típico. 1. BIOS BIOS significa Basic Input/Output System. Em termos simples, o BIOS carrega e executa o carregador ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/o-processo-de-inicializacao-do-linux-6-etapas-descritas-em-detalhes/</link>
                <guid isPermaLink="false">61f1dab153557304fa19be6e</guid>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Fernando Mota Freitas ]]>
                </dc:creator>
                <pubDate>Thu, 03 Feb 2022 14:34:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/01/5f9c9cef740569d1a4ca34fc-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/the-linux-booting-process-6-steps-described-in-detail/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Linux Booting Process - 6 Steps Described in Detail</a>
      </p><p>Um sistema operacional (SO) é o software de baixo nível que gerencia recursos, controla periféricos e fornece serviços básicos para outros softwares. No Linux, existem 6 estágios distintos no processo de inicialização típico.</p><h3 id="1-bios"><strong>1. BIOS</strong></h3><p>BIOS significa Basic Input/Output System. Em termos simples, o BIOS carrega e executa o carregador de inicialização Master Boot Record (MBR).</p><p>Quando você liga o computador pela primeira vez, a primeira coisa que o BIOS faz é executar algumas verificações de integridade do HDD ou SSD.</p><p>Em seguida, o BIOS procura, carrega e executa o programa carregador de inicialização, que pode ser encontrado no Master Boot Record (MBR). O MBR às vezes está em um pendrive ou CD-ROM, como em uma instalação em formato live-USB do Linux.</p><p>Uma vez que o programa carregador de inicialização é detectado, ele é carregado na memória e o BIOS dá o controle do sistema a ele.</p><h3 id="2-mbr"><strong>2. MBR</strong></h3><p>MBR significa Master Boot Record e é responsável por carregar e executar o carregador de inicialização GRUB.</p><p>O MBR está localizado no 1º setor do disco inicializável, que normalmente é <code>/dev/hda</code> ou <code>/dev/sda</code>, dependendo do seu hardware. O MBR também contém informações sobre o GRUB, ou LILO em sistemas muito antigos.</p><h3 id="3-grub"><strong>3. GRUB</strong></h3><p>Às vezes chamado de GNU GRUB, que é a abreviação de GNU GR e Unified Bootloader, é o carregador de inicialização típico para a maioria dos sistemas Linux modernos.</p><p>A tela inicial do GRUB geralmente é a primeira coisa que você vê quando inicializa seu computador. Tem um menu simples onde você pode selecionar algumas opções. Se você tiver várias imagens de kernel instaladas, poderá usar o teclado para selecionar aquela com a qual deseja que seu sistema inicialize. Por padrão, a imagem do kernel mais recente é selecionada.</p><p>A tela inicial aguarda alguns segundos para você selecionar uma opção. Se você não fizer isso, ele carregará a imagem padrão do kernel.</p><p>Em muitos sistemas, você pode encontrar o arquivo de configuração do GRUB em <code>/boot/grub/grub.conf</code> ou <code>/etc/grub.conf</code>. Aqui está um exemplo de um arquivo <code>grub.conf</code> simples:</p><pre><code class="language-text">#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-194.el5PAE)
      root (hd0,0)
      kernel /boot/vmlinuz-2.6.18-194.el5PAE ro root=LABEL=/
      initrd /boot/initrd-2.6.18-194.el5PAE.img</code></pre><h3 id="4-n-cleo"><strong>4. Núcleo</strong></h3><p>O kernel é muitas vezes referido como o núcleo de qualquer sistema operacional, incluindo o Linux. Ele tem controle total sobre tudo em seu sistema.</p><p>Neste estágio do processo de inicialização, o kernel que foi selecionado pelo GRUB primeiro monta o sistema de arquivos raiz especificado no arquivo <code>grub.conf</code>. Em seguida, executa o programa <code>/sbin/init</code>, que é sempre o primeiro programa a ser executado. Você pode confirmar isso com seu ID de processo (PID), que deve ser sempre 1.</p><p>O kernel então estabelece um sistema de arquivos raiz temporário usando o disco RAM inicial (initrd) até que o sistema de arquivos real seja montado.</p><h3 id="5-iniciar"><strong>5. Iniciar</strong></h3><p>Neste ponto, seu sistema executa programas de nível de execução. Em um ponto, ele procuraria um arquivo init, geralmente encontrado em <code>/etc/inittab</code>para decidir o nível de execução do Linux.</p><p>Os sistemas Linux modernos usam o systemd para escolher um nível de execução. De acordo com a <a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;client=webapp&amp;u=https://www.tecmint.com/change-runlevels-targets-in-systemd/">TecMint</a> , estes são os níveis de execução disponíveis:</p><blockquote><strong>O nível de execução 0</strong> é correspondido por <strong>poweroff.target</strong> (e <strong>runlevel0.target</strong> é um link simbólico para <strong>poweroff.target</strong> ). <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>O nível de execução 1</strong> é correspondido por <strong>rescue.target</strong> (e <strong>runlevel1.target</strong> é um link simbólico para <strong>rescue.target</strong> ). <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>O nível de execução</strong> 3 é emulado por <strong>multi-user.target</strong> (e <strong>runlevel3.target</strong> é um link simbólico para <strong>multi-user.target</strong> ). <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>O nível de execução 5</strong> é emulado por <strong>graphical.target</strong>(e <strong>runlevel5.target</strong> é um link simbólico para <strong>graphical.target</strong> ). <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>O nível de execução 6</strong> é emulado por <strong>reboot.target</strong> (e <strong>runlevel6.target</strong> é um link simbólico para <strong>reboot.target</strong> ). <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>Emergency</strong> é correspondido por <strong>Emergency.target</strong> .</blockquote><p>O systemd então começará a executar programas de nível de execução.</p><h3 id="6-programas-de-n-vel-de-execu-o"><strong>6. Programas de nível de execução</strong></h3><p>Dependendo de qual distribuição Linux você instalou, você poderá ver diferentes serviços sendo iniciados. Por exemplo, você pode pegar <code>starting sendmail …. OK</code>.</p><p>Eles são conhecidos como programas de nível de execução e são executados a partir de diretórios diferentes, dependendo do nível de execução. Cada um dos 6 níveis de execução descritos acima tem seu próprio diretório:</p><ul><li>Nível de execução 0 –<code>/etc/rc0.d/</code></li><li>Nível de execução 1 –<code>/etc/rc1.d/</code></li><li>Nível de execução 2 –<code>/etc/rc2.d/</code></li><li>Nível de execução 3 –<code>/etc/rc3.d/</code></li><li>Nível de execução 4 –<code>/etc/rc4.d/</code></li><li>Nível de execução 5 –<code>/etc/rc5.d/</code></li><li>Nível de execução 6 –<code>/etc/rc6.d/</code></li></ul><p>Observe que a localização exata desses diretórios varia de distribuição para distribuição.</p><p>Se você procurar nos diferentes diretórios de nível de execução, encontrará programas que começam com "S" ou "K" para inicialização e eliminação, respectivamente. Os programas de inicialização são executados durante a inicialização do sistema e eliminam os programas durante o desligamento.</p><p>Isso é tudo que você precisa saber sobre o processo de inicialização do Linux. Agora vá lá e deixe <a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;client=webapp&amp;u=https://en.wikipedia.org/wiki/Tux_(mascot)">Tux</a> orgulhoso.</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
