Próximo: , Acima: Desenvolvimento   [Conteúdo][Índice]


7.1 Invocando guix shell

O propósito do guix shell é facilitar a criação de ambientes de software únicos, sem alterar o perfil. Ele é normalmente usado para criar ambientes de desenvolvimento; também é uma maneira conveniente de executar aplicativos sem “poluir” seu perfil.

Nota: O comando guix shell foi introduzido recentemente para substituir guix environment (veja Invocando guix environment). Se você estiver familiarizado com guix environment, notará que ele é semelhante, mas também—esperamos!—mais conveniente.

A sintaxe geral é:

guix shell [opções] [pacote…]

Às vezes, uma sessão de shell interativa não é desejada. Um comando arbitrário pode ser invocado colocando o token -- para separar o comando do resto dos argumentos.

O exemplo a seguir cria um ambiente contendo Python e NumPy, compilando ou baixando qualquer pacote ausente e executa o comando python3 nesse ambiente:

guix shell python python-numpy -- python3

Note que é necessário incluir o pacote principal python neste comando, mesmo que ele já esteja instalado em seu ambiente. Isso é para que o ambiente shell saiba definir PYTHONPATH e outras variáveis relacionadas. O ambiente shell não pode verificar o ambiente instalado anteriormente, porque então seria não determinístico. Isso é verdade para a maioria das bibliotecas: seu pacote de linguagem correspondente deve ser incluído na invocação do shell.

Nota: guix shell também pode ser usado como um interpretador de script, também conhecido como shebang. Aqui está um exemplo de script Python autocontido fazendo uso desse recurso:

#!/usr/bin/env -S guix shell python python-numpy -- python3
import numpy
print("This is numpy", numpy.version.version)

Você pode passar qualquer opção guix shell, mas há uma ressalva: o kernel Linux tem um limite de 127 bytes no comprimento do shebang.

Ambientes de desenvolvimento podem ser criados como no exemplo abaixo, que gera um shell interativo contendo todas as dependências e variáveis de ambiente necessárias para trabalhar no Inkscape:

guix shell --development inkscape

Sair do shell coloca o usuário de volta no ambiente original antes de guix shell ser invocado. A próxima coleta de lixo (veja Invocando guix gc) pode limpar pacotes que foram instalados no ambiente e que não são mais usados fora dele.

Como uma conveniência adicional, guix shell tentará fazer o que você quer dizer quando for invocado interativamente sem nenhum outro argumento, como em:

guix shell

Se encontrar um manifest.scm no diretório de trabalho atual ou em qualquer um dos seus pais, ele usa esse manifesto como se tivesse sido fornecido via --manifest. Da mesma forma, se encontrar um guix.scm nos mesmos diretórios, ele o usa para construir um perfil de desenvolvimento como se --development e --file estivessem presentes. Em ambos os casos, o arquivo só será carregado se o diretório em que ele reside estiver listado em ~/.config/guix/shell-authorized-directories. Isso fornece uma maneira fácil de definir, compartilhar e entrar em ambientes de desenvolvimento.

Por padrão, a sessão ou comando do shell é executado em um ambiente aumentado, onde os novos pacotes são adicionados às variáveis de ambiente do caminho de pesquisa, como PATH. Em vez disso, você pode escolher criar um ambiente isolado contendo apenas os pacotes solicitados. Passar a opção --pure limpa as definições de variáveis de ambiente encontradas no ambiente pai14; passar --container vai um passo além ao gerar um contêiner isolado do resto do sistema:

guix shell --container emacs gcc-toolchain

O comando acima gera um shell interativo em um contêiner onde nada além de emacs, gcc-toolchain e suas dependências estão disponíveis. O contêiner não tem acesso à rede e não compartilha nenhum arquivo além do diretório de trabalho atual com o ambiente ao redor. Isso é útil para evitar acesso a recursos de todo o sistema, como /usr/bin em distros estrangeiras.

Esta opção --container também pode ser útil se você deseja executar um aplicativo sensível à segurança, como um navegador da web, em um ambiente isolado. Por exemplo, o comando abaixo inicia o Ungoogled-Chromium em um ambiente isolado, que:

guix shell --container --network --no-cwd ungoogled-chromium \
  --preserve='^XAUTHORITY$' --expose="${XAUTHORITY}" \
  --preserve='^DISPLAY$' -- chromium

guix shell define a variável GUIX_ENVIRONMENT no shell que ele gera; seu valor é o nome do arquivo do perfil deste ambiente. Isso permite que os usuários, digamos, definam um prompt específico para ambientes de desenvolvimento em seu .bashrc (veja Bash Startup Files em Manual de referência do GNU Bash):

if [ -n "$GUIX_ENVIRONMENT" ]
then
    export PS1="\u@\h \w [dev]\$ "
fi

... ou para navegar pelo perfil:

$ ls "$GUIX_ENVIRONMENT/bin"

As opções disponíveis estão resumidas abaixo.

--check

Configure o ambiente e verifique se o shell sobrecarregaria as variáveis de ambiente. É uma boa ideia usar esta opção na primeira vez que você executar guix shell para uma sessão interativa para garantir que sua configuração esteja correta.

Por exemplo, se o shell modificar a variável de ambiente PATH, informe isso, pois você obterá um ambiente diferente do que solicitou.

Tais problemas geralmente indicam que os arquivos de inicialização do shell estão modificando inesperadamente essas variáveis de ambiente. Por exemplo, se você estiver usando Bash, certifique-se de que as variáveis de ambiente estejam definidas ou modificadas em ~/.bash_profile e não em ~/.bashrc—o primeiro é originado apenas por shells de login. Veja Bash Startup Files em Manual de referência do GNU Bash, para detalhes sobre os arquivos de inicialização do Bash.

--development
-D

Faça com que guix shell inclua no ambiente as dependências do pacote a seguir em vez do pacote em si. Isso pode ser combinado com outros pacotes. Por exemplo, o comando abaixo inicia um shell interativo contendo as dependências de tempo de compilação do GNU Guile, além do Autoconf, Automake e Libtool:

guix shell -D guile autoconf automake libtool
--expression=expr
-e expr

Crie um ambiente para o pacote ou lista de pacotes que expr avalia.

Por exemplo, executando:

guix shell -D -e '(@ (gnu packages maths) petsc-openmpi)'

inicia um shell com o ambiente para esta variante específica do pacote PETSc.

Rodando:

guix shell -e '(@ (gnu) %base-packages)'

inicia um shell com todos os pacotes do sistema base disponíveis.

Os comandos acima usam apenas a saída padrão dos pacotes fornecidos. Para selecionar outras saídas, duas tuplas de elementos podem ser especificadas:

guix shell -e '(list (@ (gnu packages bash) bash) "include")'

Veja package->development-manifest, para obter informações sobre como escrever um manifesto para o ambiente de desenvolvimento de um pacote.

--file=arquivo
-f arquivo

Crie um ambiente contendo o pacote ou lista de pacotes que o código dentro de arquivo avalia.

Por exemplo, arquivo pode conter uma definição como esta (veja Definindo pacotes):

(use-modules (guix)
             (gnu packages gdb)
             (gnu packages autotools)
             (gnu packages texinfo))

;; Augment the package definition of GDB with the build tools
;; needed when developing GDB (and which are not needed when
;; simply installing it.)
(package
  (inherit gdb)
  (native-inputs (modify-inputs (package-native-inputs gdb)
                   (prepend autoconf-2.69 automake texinfo))))

Com o arquivo acima, você pode entrar em um ambiente de desenvolvimento para o GDB executando:

guix shell -D -f gdb-devel.scm
--manifest=arquivo
-m arquivo

Crie um ambiente para os pacotes contidos no objeto manifest retornado pelo código Scheme em arquivo. Esta opção pode ser repetida várias vezes, nesse caso os manifestos são concatenados.

Isso é semelhante à opção de mesmo nome em guix package (veja --manifest) e usa os mesmos arquivos de manifesto.

Veja Escrevendo manifestos, para informações sobre como escrever um manifesto. Veja --export-manifest abaixo sobre como obter um primeiro manifesto.

--export-manifest

Grave na saída padrão um manifesto adequado para --manifest correspondente às opções de linha de comando fornecidas.

Esta é uma maneira de “converter” argumentos de linha de comando em um manifesto. Por exemplo, imagine que você está cansado de digitar linhas longas e gostaria de obter um manifesto equivalente a esta linha de comando:

guix shell -D guile git emacs emacs-geiser emacs-geiser-guile

Basta adicionar --export-manifest à linha de comando acima:

guix shell --export-manifest \
  -D guile git emacs emacs-geiser emacs-geiser-guile

... and you get a manifest along these lines:

(concatenate-manifests
  (list (specifications->manifest
          (list "git"
                "emacs"
                "emacs-geiser"
                "emacs-geiser-guile"))
        (package->development-manifest
          (specification->package "guile"))))

Você pode armazená-lo em um arquivo, digamos manifest.scm, e de lá passá-lo para guix shell ou praticamente qualquer comando guix:

guix shell -m manifest.scm

Voilà, você converteu uma longa linha de comando em um manifesto! Esse processo de conversão honra opções de transformação de pacote (veja Opções de transformação de pacote), então deve ser sem perdas.

--profile=perfil
-p perfil

Crie um ambiente contendo os pacotes instalados em perfil. Use guix package (veja Invocando guix package) para criar e gerenciar perfis.

--pure

Desconfigura variáveis de ambiente existentes ao construir o novo ambiente, exceto aquelas especificadas com --preserve (veja abaixo). Isso tem o efeito de criar um ambiente no qual os caminhos de pesquisa contêm apenas entradas de pacote.

--preserve=regexp
-E regexp

Quando usado junto com --pure, preserva as variáveis de ambiente que correspondem a regexp—em outras palavras, coloca-as em uma “lista branca” de variáveis de ambiente que devem ser preservadas. Esta opção pode ser repetida várias vezes.

guix shell --pure --preserve=^SLURM openmpi … \
  -- mpirun …

Este exemplo executa mpirun em um contexto onde as únicas variáveis de ambiente definidas são PATH, variáveis de ambiente cujo nome começa com ‘SLURM’, bem como as variáveis “preciosas” usuais (HOME, USER, etc.).

--search-paths

Exiba as definições de variáveis de ambiente que compõem o ambiente.

--system=sistema
-s sistema

Tente construir para sistema—por exemplo, i686-linux.

--container
-C

Execute comando dentro de um contêiner isolado. O diretório de trabalho atual fora do contêiner é mapeado dentro do contêiner. Além disso, a menos que substituído por --user, um diretório pessoal (home) fictício é criado que corresponde ao diretório pessoal do usuário atual, e /etc/passwd é configurado adequadamente.

O processo gerado é executado como o usuário atual fora do contêiner. Dentro do contêiner, ele tem o mesmo UID e GID que o usuário atual, a menos que --user seja passado (veja abaixo).

--network
-N

Para contêineres, compartilhe o namespace de rede com o sistema host. Os contêineres criados sem esse sinalizador têm acesso somente ao dispositivo de loopback.

--link-profile
-P

Para contêineres, vincule o perfil do ambiente a ~/.guix-profile dentro do contêiner e defina GUIX_ENVIRONMENT para isso. Isso é equivalente a tornar ~/.guix-profile uma ligação simbólica para o perfil real dentro do contêiner. A vinculação falhará e abortará o ambiente se o diretório já existir, o que certamente será o caso se guix shell foi invocado no diretório pessoal do usuário.

Certos pacotes são configurados para procurar em ~/.guix-profile por arquivos de configuração e dados;15 --link-profile permite que esses programas se comportem conforme o esperado no ambiente.

--user=usuário
-u usuário

Para contêineres, use o nome de usuário usuário no lugar do usuário atual. A entrada /etc/passwd gerada dentro do contêiner conterá o nome usuário, o diretório pessoal será /home/usuário e nenhum dado GECOS do usuário será copiado. Além disso, o UID e o GID dentro do contêiner são 1000. usuário não precisa existir no sistema.

Além disso, qualquer caminho compartilhado ou exposto (veja --share e --expose respectivamente) cujo destino esteja dentro do pessoal do usuário atual será remapeado em relação a /home/USUÁRIO; isso inclui o mapeamento automático do diretório de trabalho atual.

# will expose paths as /home/foo/wd, /home/foo/test, and /home/foo/target
cd $HOME/wd
guix shell --container --user=foo \
     --expose=$HOME/test \
     --expose=/tmp/target=$HOME/target

Embora isso limite o vazamento da identidade do usuário por meio de caminhos iniciais e de cada um dos campos do usuário, esse é apenas um componente útil de uma solução mais ampla de privacidade/anonimato — não uma solução em si.

--no-cwd

Para contêineres, o comportamento padrão é compartilhar o diretório de trabalho atual com o contêiner isolado e mudar imediatamente para esse diretório dentro do contêiner. Se isso for indesejável, --no-cwd fará com que o diretório de trabalho atual não seja compartilhado automaticamente e mudará para o diretório pessoal do usuário dentro do contêiner. Veja também --user.

--expose=fonte[=alvo]
--share=fonte[=alvo]

Para contêineres, --expose (resp. --share) expõe o sistema de arquivos fonte do sistema host como o sistema de arquivos somente leitura (resp. gravável) alvo dentro do contêiner. Se alvo não for especificado, fonte será usado como o ponto de montagem de destino no contêiner.

O exemplo abaixo gera um Guile REPL em um contêiner no qual o diretório pessoal do usuário é acessível somente para leitura por meio do diretório /exchange:

guix shell --container --expose=$HOME=/exchange guile -- guile
--symlink=spec
-S spec

Para contêineres, crie as ligações simbólicas especificadas por spec, conforme documentado em pack-symlink-option.

--emulate-fhs
-F

Quando usado com --container, emule uma configuração do FHS) dentro do contêiner, fornecendo /bin, /lib e outros diretórios e arquivos especificados pelo FHS.

Como Guix desvia da especificação FHS, esta opção configura o contêiner para imitar mais de perto o de outras distribuições GNU/Linux. Isto é útil para reproduzir outros ambientes de desenvolvimento, testar e usar programas que esperam que a especificação FHS seja seguida. Com esta opção, o contêiner incluirá uma versão do glibc que lerá /etc/ld.so.cache dentro do contêiner para o cache da biblioteca compartilhada (ao contrário do glibc no uso regular do Guix) e configurará os diretórios FHS esperados: /bin, /etc, /lib e /usr do perfil do contêiner.

--nesting
-W

Quando usado com --container, forneça Guix dentro do contêiner e organize para que ele possa interagir com o daemon de construção que roda fora do contêiner. Isso é útil se você quiser, dentro do seu contêiner isolado, criar outros contêineres, como nesta sessão de exemplo:

$ guix shell -CW coreutils
[env]$ guix shell -C guile -- guile -c '(display "olá!\n")'
olá!
[env]$ exit

A sessão acima inicia um contêiner com programas coreutils disponíveis em PATH. A partir daí, geramos guix shell para criar um contêiner aninhado que fornece nada além de Guile.

Outro exemplo é avaliar um arquivo guix.scm que não é confiável, conforme mostrado aqui:

guix shell -CW -- guix build -f guix.scm

O comando guix build executado acima só pode acessar o diretório atual.

Nos bastidores, a opção -W faz várias coisas:

  • mapeia o socket do daemon (por padrão, /var/guix/daemon-socket/socket) dentro do contêiner;
  • mapeia todo o armazém (por padrão /gnu/store) dentro do contêiner de forma que os itens do armazém disponibilizados por invocações aninhadas guix sejam visíveis;
  • adiciona o comando guix usado atualmente ao perfil no contêiner, de modo que guix describe retorne o mesmo estado dentro e fora do contêiner;
  • compartilha o cache (por padrão ~/.cache/guix) com o host, para acelerar operações como guix time-machine e guix shell.
--rebuild-cache

Na maioria dos casos, guix shell armazena em cache o ambiente para que os usos subsequentes sejam instantâneos. As entradas de cache menos usadas recentemente são removidas periodicamente. O cache também é invalidado, ao usar --file ou --manifest, sempre que o arquivo correspondente for modificado.

O --rebuild-cache força o ambiente em cache a ser atualizado. Isso é útil ao usar --file ou --manifest e o arquivo guix.scm ou manifest.scm tem dependências externas, ou se seu comportamento depende, digamos, de variáveis de ambiente.

--root=arquivo
-r arquivo

Crie arquivo como uma ligação simbólica para o perfil deste ambiente e registre-a como raiz do coletor de lixo.

Isso é útil se você deseja proteger seu ambiente da coleta de lixo, para torná-lo “persistente”.

Quando esta opção é omitida, guix shell armazena em cache os perfis para que os usos subsequentes do mesmo ambiente sejam instantâneos — isso é comparável ao uso de --root, exceto que guix shell cuida da remoção periódica das raízes do coletor de lixo menos usadas recentemente.

Em alguns casos, guix shell não armazena perfis em cache—por exemplo, se opções de transformação como --with-latest forem usadas. Nesses casos, o ambiente é protegido da coleta de lixo somente durante a sessão guix shell. Isso significa que na próxima vez que você recriar o mesmo ambiente, poderá ter que reconstruir ou baixar novamente os pacotes.

Veja Invocando guix pack, para mais sobre as raízes do coletor de lixo.

guix shell também suporta todas as opções de compilação comuns que guix build suporta (veja Opções de compilação comuns), bem como opções de transformação de pacotes (veja Opções de transformação de pacote).


Notas de Rodapé

(14)

Certifique-se de usar a opção --check na primeira vez que usar guix shell interativamente para garantir que o shell não desfaça o efeito de --pure.

(15)

Por exemplo, o pacote fontconfig inspeciona ~/.guix-profile/share/fonts por fontes adicionais.


Próximo: Invocando guix environment, Acima: Desenvolvimento   [Conteúdo][Índice]