{"id":122,"date":"2017-05-04T21:09:03","date_gmt":"2017-05-05T00:09:03","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/2017\/05\/instalando-golang-no-linux\/"},"modified":"2026-09-08T03:38:31","modified_gmt":"2026-09-08T06:38:31","slug":"instalando-golang-no-linux","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/en\/2017\/05\/instalando-golang-no-linux\/","title":{"rendered":"Go no Ubuntu: instalando e escrevendo seu primeiro programa"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" alt=\"Mascote do LinuxPro digitando no laptop com o primeiro programa compilando no terminal, ao lado do gopher do Go\" src=\"\/wp-content\/uploads\/2026\/09\/golang-v4.webp\" width=\"1052\" height=\"652\" \/><\/p>\n<div style=\"background:#fff8e1;border-left:4px solid #8b1a1a;padding:.8em 1em;margin:1em 0\"><strong>Nota (2026):<\/strong> Este post era, em 2017, a instala\u00e7\u00e3o do Go 1.8.3 com <code data-no-translation=\"\">GOPATH<\/code> \u2014 um jeito de trabalhar que a pr\u00f3pria linguagem abandonou. Reescrevemos como um <em>hello world<\/em> de verdade no Ubuntu, com a vers\u00e3o atual e com m\u00f3dulos.<\/div>\n<p>Este \u00e9 o caminho mais curto entre um Ubuntu limpo e o seu primeiro programa em <strong>Go<\/strong> rodando. Leva uns dez minutos, e no fim voc\u00ea sai com um bin\u00e1rio \u00fanico que roda em qualquer Linux \u2014 sem interpretador, sem m\u00e1quina virtual, sem depend\u00eancia para instalar no servidor.<\/p>\n<h2>Por que Go, em duas frases<\/h2>\n<p>O Go foi desenhado no Google em 2007 porque o C++ demorava demais para compilar e a concorr\u00eancia dava trabalho demais. O resultado: compila em segundos, tem concorr\u00eancia embutida na linguagem e entrega um <strong>bin\u00e1rio est\u00e1tico<\/strong>. \u00c9 por isso que Docker, Kubernetes, Terraform e Prometheus s\u00e3o escritos nele. A hist\u00f3ria completa est\u00e1 em <a href=\"\/en\/2026\/09\/a-historia-da-linguagem-go\/\">A hist\u00f3ria da linguagem Go<\/a>.<\/p>\n<h2>Instalando no Ubuntu<\/h2>\n<p>Existem tr\u00eas caminhos. O <strong>tarball oficial \u00e9 o recomendado<\/strong> \u2014 o pacote do <code data-no-translation=\"\">apt<\/code> costuma ficar uma ou duas vers\u00f5es atr\u00e1s, e no Go isso importa porque a linguagem lan\u00e7a a cada seis meses.<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\"># descobre a vers\u00e3o atual sem abrir o navegador\nVER=$(curl -fsSL 'https:\/\/go.dev\/VERSION?m=text' | head -n1)\necho \"$VER\"\n\n# baixa e instala no lugar can\u00f4nico\ncd \/tmp\ncurl -fLO \"https:\/\/go.dev\/dl\/${VER}.linux-amd64.tar.gz\"\nsudo rm -rf \/usr\/local\/go\nsudo tar -C \/usr\/local -xzf \"${VER}.linux-amd64.tar.gz\"<\/code><\/pre>\n<p>Repare no <code data-no-translation=\"\">rm -rf \/usr\/local\/go<\/code> antes de extrair: \u00e9 o passo que a documenta\u00e7\u00e3o oficial exige e que quase todo tutorial esquece. Extrair por cima de uma instala\u00e7\u00e3o antiga mistura arquivos de duas vers\u00f5es e gera erro dif\u00edcil de diagnosticar.<\/p>\n<p>Agora o <code data-no-translation=\"\">PATH<\/code>. Para valer no sistema inteiro e sobreviver a novos usu\u00e1rios:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">echo 'export PATH=$PATH:\/usr\/local\/go\/bin' | sudo tee \/etc\/profile.d\/go.sh\nsource \/etc\/profile.d\/go.sh\n\ngo version<\/code><\/pre>\n<p>Se apareceu algo como <code data-no-translation=\"\">go version go1.27.1 linux\/amd64<\/code>, est\u00e1 pronto. Se o comando n\u00e3o foi encontrado, o <code data-no-translation=\"\">source<\/code> acima resolve na sess\u00e3o atual \u2014 nas pr\u00f3ximas ele carrega sozinho.<\/p>\n<p>Em m\u00e1quina ARM, como um Raspberry Pi, troque <code data-no-translation=\"\">linux-amd64<\/code> by <code data-no-translation=\"\">linux-arm64<\/code>.<\/p>\n<h3>As alternativas, e quando us\u00e1-las<\/h3>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\"># snap \u2014 vers\u00e3o recente, atualiza sozinho\nsudo snap install go --classic\n\n# apt \u2014 mais simples, vers\u00e3o mais velha\nsudo apt install golang-go<\/code><\/pre>\n<p>The <code data-no-translation=\"\">apt<\/code> serve se voc\u00ea s\u00f3 precisa compilar algo de terceiro e n\u00e3o se importa com a vers\u00e3o. Para desenvolver, fique no tarball.<\/p>\n<h2>Hello, world<\/h2>\n<p>Antes de qualquer estrutura de projeto, veja a linguagem nua. Crie <code data-no-translation=\"\">ola.go<\/code>:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-go\" data-no-translation=\"\">package main\n\nimport \"fmt\"\n\nfunc main() {\n    fmt.Println(\"Ol\u00e1, mundo!\")\n}<\/code><\/pre>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">go run ola.go<\/code><\/pre>\n<p>The <code data-no-translation=\"\">go run<\/code> compila e executa em mem\u00f3ria, sem deixar bin\u00e1rio \u2014 \u00e9 o modo de experimentar. Tr\u00eas coisas para reparar: todo programa execut\u00e1vel come\u00e7a em <code data-no-translation=\"\">package main<\/code>; a fun\u00e7\u00e3o de entrada \u00e9 <code data-no-translation=\"\">func main()<\/code>; e o <code data-no-translation=\"\">import<\/code> \u00e9 obrigat\u00f3rio e <strong>n\u00e3o pode sobrar<\/strong>. Se voc\u00ea importar um pacote e n\u00e3o usar, o Go se recusa a compilar. \u00c9 r\u00edgido de prop\u00f3sito.<\/p>\n<h2>Agora do jeito certo: um m\u00f3dulo<\/h2>\n<p>Na pr\u00e1tica ningu\u00e9m trabalha com arquivo solto. O Go organiza projeto em <strong>m\u00f3dulos<\/strong> desde a vers\u00e3o 1.11, e essa \u00e9 a mudan\u00e7a que aposentou o velho <code data-no-translation=\"\">GOPATH<\/code> deste post em 2017:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">mkdir ~\/ola &amp;&amp; cd ~\/ola\ngo mod init exemplo.com\/ola<\/code><\/pre>\n<p>Isso cria o <code data-no-translation=\"\">go.mod<\/code>, que declara o nome do m\u00f3dulo e a vers\u00e3o da linguagem. Agora um programa um pouco mais interessante \u2014 crie <code data-no-translation=\"\">main.go<\/code>:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-go\" data-no-translation=\"\">package main\n\nimport (\n    \"bufio\"\n    \"fmt\"\n    \"os\"\n    \"strings\"\n)\n\nfunc main() {\n    fmt.Print(\"Qual o seu nome? \")\n\n    leitor := bufio.NewReader(os.Stdin)\n    nome, err := leitor.ReadString('n')\n    if err != nil {\n        fmt.Fprintln(os.Stderr, \"erro ao ler a entrada:\", err)\n        os.Exit(1)\n    }\n\n    nome = strings.TrimSpace(nome)\n    if nome == \"\" {\n        fmt.Println(\"Voc\u00ea n\u00e3o digitou nada.\")\n        return\n    }\n\n    fmt.Printf(\"Ol\u00e1, %s! Bem-vindo ao Go.n\", nome)\n}<\/code><\/pre>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">go run .<\/code><\/pre>\n<p>Aqui aparece a marca registrada da linguagem: o <code data-no-translation=\"\">if err != nil<\/code>. Em Go n\u00e3o existe exce\u00e7\u00e3o \u2014 toda fun\u00e7\u00e3o que pode falhar devolve o erro junto com o resultado, e voc\u00ea \u00e9 obrigado a decidir o que fazer com ele. \u00c9 verboso, \u00e9 criticado, e \u00e9 intencional: o caminho do erro fica vis\u00edvel no c\u00f3digo, n\u00e3o escondido num <code data-no-translation=\"\">catch<\/code> distante.<\/p>\n<h2>Gerando o bin\u00e1rio<\/h2>\n<p>Esta \u00e9 a parte que vende a linguagem para quem administra servidor:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">go build -o ola\nls -lh ola\n.\/ola<\/code><\/pre>\n<p>O arquivo <code data-no-translation=\"\">ola<\/code> \u00e9 um execut\u00e1vel completo. Copie para outro Linux e ele roda \u2014 n\u00e3o \u00e9 preciso instalar o Go l\u00e1, nem runtime, nem biblioteca. E d\u00e1 para compilar para outro sistema sem sair do seu:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">GOOS=linux   GOARCH=arm64 go build -o ola-arm      # Raspberry Pi\nGOOS=windows GOARCH=amd64 go build -o ola.exe      # Windows\nGOOS=darwin  GOARCH=arm64 go build -o ola-mac      # Mac com Apple Silicon<\/code><\/pre>\n<p>Compila\u00e7\u00e3o cruzada em uma vari\u00e1vel de ambiente, sem toolchain extra. \u00c9 por isso que tanta ferramenta de linha de comando moderna \u00e9 distribu\u00edda como um bin\u00e1rio por plataforma.<\/p>\n<h2>Usando uma depend\u00eancia<\/h2>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">go get github.com\/fatih\/color<\/code><\/pre>\n<pre data-no-translation=\"\"><code class=\"language-go\" data-no-translation=\"\">package main\n\nimport \"github.com\/fatih\/color\"\n\nfunc main() {\n    color.Green(\"Ol\u00e1, mundo!\")\n    color.New(color.FgYellow, color.Bold).Println(\"agora em amarelo e negrito\")\n}<\/code><\/pre>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">go mod tidy    # ajusta o go.mod: adiciona o que falta, remove o que sobra\ngo run .<\/code><\/pre>\n<p>The <code data-no-translation=\"\">go.sum<\/code>, criado automaticamente, guarda o hash de cada depend\u00eancia \u2014 \u00e9 o que garante que a vers\u00e3o baixada amanh\u00e3 \u00e9 byte a byte a mesma de hoje. <strong>Versione os dois arquivos<\/strong>, <code data-no-translation=\"\">go.mod<\/code> and <code data-no-translation=\"\">go.sum<\/code>, junto com o c\u00f3digo.<\/p>\n<h2>Um gostinho de concorr\u00eancia<\/h2>\n<p>N\u00e3o d\u00e1 para apresentar Go sem mostrar a <em>goroutine<\/em>, que \u00e9 o motivo de a linguagem ter ganhado a infraestrutura:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-go\" data-no-translation=\"\">package main\n\nimport (\n    \"fmt\"\n    \"net\/http\"\n    \"time\"\n)\n\nfunc checar(url string, resultado chan&lt;- string) {\n    inicio := time.Now()\n    resp, err := http.Get(url)\n    if err != nil {\n        resultado &lt;- fmt.Sprintf(\"%-28s ERRO: %v\", url, err)\n        return\n    }\n    defer resp.Body.Close()\n    resultado &lt;- fmt.Sprintf(\"%-28s %s em %v\", url, resp.Status, time.Since(inicio).Round(time.Millisecond))\n}\n\nfunc main() {\n    sites := []string{\n        \"https:\/\/www.linuxpro.com.br\",\n        \"https:\/\/go.dev\",\n        \"https:\/\/kernel.org\",\n    }\n\n    resultado := make(chan string)\n    for _, s := range sites {\n        go checar(s, resultado)     \/\/ dispara os tr\u00eas ao mesmo tempo\n    }\n\n    for range sites {\n        fmt.Println(&lt;-resultado)    \/\/ recebe conforme forem chegando\n    }\n}<\/code><\/pre>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">go run .<\/code><\/pre>\n<p>Os tr\u00eas sites s\u00e3o consultados <strong>em paralelo<\/strong>, e o total demora o tempo do mais lento, n\u00e3o a soma dos tr\u00eas. Isso \u00e9 uma palavra \u2014 <code data-no-translation=\"\">go<\/code> \u2014 e um canal. Sem biblioteca, sem pool de threads, sem <em>callback<\/em>.<\/p>\n<h2>As ferramentas que j\u00e1 v\u00eam juntas<\/h2>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">go fmt .\/...      # formata no padr\u00e3o oficial; n\u00e3o h\u00e1 debate de estilo em Go\ngo vet .\/...      # aponta erro prov\u00e1vel que compila mesmo assim\ngo test .\/...     # roda os testes\ngo doc fmt.Println   # documenta\u00e7\u00e3o sem sair do terminal\ngo clean -cache   # limpa o cache de build quando algo fica estranho<\/code><\/pre>\n<p>The <code data-no-translation=\"\">go fmt<\/code> merece destaque: a linguagem tem <em>a<\/em> estilo oficial, aplicado por ferramenta. Isso encerrou, de sa\u00edda, a discuss\u00e3o sobre tabula\u00e7\u00e3o e chaves que consome tempo em outras comunidades.<\/p>\n<h2>V\u00e1rias vers\u00f5es na mesma m\u00e1quina<\/h2>\n<p>Quando um projeto est\u00e1 preso numa vers\u00e3o antiga, o pr\u00f3prio Go resolve \u2014 sem gerenciador externo:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">go install golang.org\/dl\/go1.26@latest\ngo1.26 download\ngo1.26 version<\/code><\/pre>\n<p>E, desde a 1.21, existe algo ainda melhor: se o <code data-no-translation=\"\">go.mod<\/code> do projeto pedir uma vers\u00e3o que voc\u00ea n\u00e3o tem, o <code data-no-translation=\"\">GOTOOLCHAIN<\/code> baixa a correta na hora do build, sozinho.<\/p>\n<h2>Por onde seguir<\/h2>\n<ul>\n<li><strong><a href=\"https:\/\/go.dev\/tour\/\" target=\"_blank\" rel=\"noopener\">A Tour of Go<\/a><\/strong> \u2014 o tutorial oficial, interativo, roda no navegador. \u00c9 a melhor porta de entrada.<\/li>\n<li><strong><a href=\"https:\/\/go.dev\/doc\/effective_go\" target=\"_blank\" rel=\"noopener\">Effective Go<\/a><\/strong> \u2014 como escrever c\u00f3digo que parece Go, e n\u00e3o Java traduzido.<\/li>\n<li>Aqui no blog: <a href=\"\/en\/2026\/09\/a-historia-da-linguagem-go\/\">A hist\u00f3ria da linguagem Go<\/a>, <a href=\"\/en\/2019\/12\/install-golang-linux\/\">o howto de instala\u00e7\u00e3o detalhado<\/a> and <a href=\"\/en\/2017\/05\/linguagens-de-programacao\/\">as principais linguagens de programa\u00e7\u00e3o<\/a>.<\/li>\n<li>Feito em Go, para estudar c\u00f3digo real: <a href=\"\/en\/2026\/09\/go-postfixadmin\/\">go-postfixadmin<\/a> and <a href=\"\/en\/2017\/04\/instalando-gogs-no-ubuntu\/\">Gogs<\/a>.<\/li>\n<\/ul>\n<p>Dez minutos, um bin\u00e1rio est\u00e1tico e um gopher azul. Bom come\u00e7o.<\/p>","protected":false},"excerpt":{"rendered":"<p>Este \u00e9 o caminho mais curto entre um Ubuntu limpo e o seu primeiro programa em Go rodando. Leva uns dez minutos, e no fim voc\u00ea sai com um bin\u00e1rio \u00fanico que roda em qualquer Linux \u2014 sem interpretador, sem &#8230; <a title=\"Go no Ubuntu: instalando e escrevendo seu primeiro programa\" class=\"read-more\" href=\"https:\/\/www.linuxpro.com.br\/en\/2017\/05\/instalando-golang-no-linux\/\" aria-label=\"Read more about Go no Ubuntu: instalando e escrevendo seu primeiro programa\">Read more<\/a><\/p>","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,3],"tags":[58,31,402,14,397,5],"class_list":["post-122","post","type-post","status-publish","format-standard","hentry","category-linux","category-ubuntu","tag-go","tag-golang","tag-gopher","tag-howto","tag-programacao","tag-ubuntu"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/comments?post=122"}],"version-history":[{"count":6,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/122\/revisions"}],"predecessor-version":[{"id":1096,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/122\/revisions\/1096"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/media?parent=122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/categories?post=122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/tags?post=122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}