Estou executando o systemd via user (ou seja enable-linger $USER
) e interajo com os serviços viasystemctl --user
Notei um problema estranho.
Fornecimento Tipo 1
Para que o systemd acima funcione para um usuário, preciso adicionar export XDG_RUNTIME_DIR=/run/user/$(id -u)
dentro do meu~/.bashrc
Isso funciona bem.
Fornecimento Tipo 2
Quando, em vez disso, procuro meu bashrc da seguinte maneira, o systemd não funciona:
dentro .bashrc
:
source /path_to_file/my_file.env
dentro my_file.env
:
XDG_RUNTIME_DIR=/run/user/$(id -u)
Tanto o Sourcing Type 1 quanto o 2 produzem o mesmo resultado quando eu faço isso, echo $XDG_RUNTIME_DIR
então decidi ir com o Type 2. No entanto, notei que quando fiz systemctl --user daemon-reload
o daemon não estava rodando e recebi o seguinte erro:
Failed to connect to bus: No such file or directory
Quando eu volto para Souring Type 1, o erro desaparece e tudo funciona conforme o esperado.
Minha pergunta é: O que está acontecendo que estou perdendo aqui? Minha principal confusão decorre do fato de que as variáveis env são as mesmas, mas os resultados finais não são.
Você esqueceu o
export
em seu arquivo .env, então a variável não é realmente uma variável de ambiente .As variáveis de shell não são exportadas para o ambiente por padrão. Apenas as atribuições a uma variável já exportada serão reexportadas automaticamente; se
XDG_RUNTIME_DIR
for uma variável totalmente nova, ela se tornará uma variável interna do shell, a menos que você use oexport
oudeclare -x
builtins. (Ou, a menos que a opção de shell "allexport" esteja habilitada, mas usá-la em .bashrc tem algumas pegadinhas estranhas.)echo $FOO
"vê" a variável porque a expansão de $FOO na linha de comando é feita pelo próprio interpretador de shell, não pelo comando - 'echo' não precisa acessar o ambiente, enquanto 'systemctl' precisa.Em vez de echo, você pode usar
declare -p FOO
para que o próprio shell informe o estado da variável (incluindo mostrar ox
sinalizador se a variável for exportada), ou usarenv
ouprintenv
para ver como o ambiente se parece do ponto de vista de um processo externo (não -variáveis de shell exportadas simplesmente não aparecerão aqui).De qualquer forma, você nunca precisará fazer isso para logins interativos. Essa variável específica deve ser colocada em seu ambiente por meio do PAM (por pam_systemd) assim que você fizer login - mesmo antes de seu shell ser executado.
Para scripts que precisam acessar os serviços de outro usuário,
systemctl --user -M ${USER}@.host
fará com que o próprio systemctl encontre o diretório de tempo de execução do usuário especificado e o soquete D-Bus.