Eu uso o WSL2 no Windows 11. Quero executar o systemctl
comando no Ubuntu 20.04, mas me dá o seguinte erro:
System has not been booted with systemd as init system (PID 1).
Can't operate. Failed to connect to bus: Host is down
Como posso corrigi-lo?
Resposta curta:
O uso mais comum de
systemctl
é iniciar serviços. Isso pode frequentemente (mas nem sempre) ser feito no Ubuntu no WSL usando:Veja abaixo mais detalhes, bem como soluções alternativas, que incluem:
service
comando em mais detalhes(Muito) explicação mais longa:
Surpreendentemente, após 5 anos ou mais de WSL, não parece haver uma boa pergunta "Systemd" de propósito geral aqui no Ask Ubuntu. Portanto, este parece ser um bom para usar para esse fim.
O problema
Em geral, quando você vê uma das duas mensagens a seguir:
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
Então é normalmente a mesma causa raiz. No caso de
systemctl
e tentando iniciarssh
, você está vendo ambos.O problema central, como mencionado nos comentários, é que o WSL não usa Systemd, mesmo em distribuições onde é o padrão. Em vez disso, o WSL atualmente usa seu próprio
/init
processo como PID 1, que executa algumas tarefas específicas do WSL que menciono nesta resposta (portanto, não as repetirei aqui).E enquanto o WSL é (IMHO) uma ótima maneira de ter um Linux CLI completo no Windows (e recentemente, até mesmo GUI), a falta do Systemd tende a tornar as coisas mais difíceis em distribuições que esperam que ele esteja lá. Felizmente, o Ubuntu é muito bom no geral sobre ser capaz de lidar sem o Systemd.
Como lidar com a falta de Systemd
E, independentemente disso, o Systemd em sua essência é apenas uma (provavelmente simplificação grosseira) "maneira de realizar tarefas do sistema". Geralmente há (mas nem sempre, veja a nota de rodapé abaixo) uma maneira de fazer a mesma tarefa sem o Systemd e, muitas vezes, mais de uma maneira.
Opção 1: "A velha maneira"
init.d
No Ubuntu no WSL, muitos dos serviços comuns do sistema ainda têm os scripts "antigos" disponíveis para serem usados no lugar dassystemctl
unidades Systemd. Você pode ver isso usandols /etc/init.d/
.Assim, por exemplo, você pode começar
ssh
comsudo service ssh start
, e ele executará o/etc/init.d/ssh
script com ostart
argumento.Mesmo alguns pacotes não padrão, como MySql/MariaDB, instalarão os arquivos da unidade Systemd e
init.d
os scripts antigos , então você ainda pode usar oservice
comando para eles.Opção 2: Docker
Muitos pacotes/serviços estão disponíveis como imagens do Docker. O Docker funciona muito bem no Ubuntu no WSL2 (especificamente no WSL2; ele não será executado no WSL1). Se não houver um script de "serviço" SysVinit para o serviço que você está tentando iniciar, pode muito bem haver uma imagem do Docker disponível que seja executada em um ambiente em contêiner.
Exemplo: Elasticsearch, como nesta pergunta e minha resposta .
Dockerfile
para ver como o serviço é iniciado sem o Systemd. Para obter mais informações, consulte a próxima opção - "A maneira manual".Opção 3: "A maneira 'manual'"
Edit: Rebaixado de sua posição anterior como "Opção 2", já que o Docker é provavelmente uma alternativa melhor para muitos serviços.
Mas alguns serviços não possuem um script de inicialização equivalente, especialmente em outras distribuições. Para simplificar, vamos supor que o
ssh
init.d
script não estava disponível.Nesse caso, a "resposta" é descobrir o que os arquivos da unidade Systemd estão fazendo e tentar replicar isso manualmente. Isso pode variar muito em complexidade. Mas eu começaria olhando para o arquivo de unidade Systemd que você está tentando executar:
Cortei algumas das linhas menos relevantes para entender seu comportamento, mas você pode
man systemd.exec
,man systemd.service
, e outros para ver o que a maioria das opções faz.Neste caso, quando você
sudo systemctl start ssh
, ele:$SSHD_OPTS
) de/etc/default/ssh
/run/sshd
(deman systemd.exec
). Isso também remove o diretório de tempo de execução quando você interrompe o serviço./usr/sbin/sshd
com opçõesPortanto, se você não tiver nenhuma configuração baseada em ambiente, basta configurar um script para:
/run
, que é umatmpfs
montagem, ele será excluído após cada reinicialização da instância WSL.0755
/usr/sbin/sshd
como root... E você teria feito a mesma coisa manualmente sem Systemd.
Novamente, este é provavelmente o exemplo mais simples. Você pode ter muito mais para trabalhar em tarefas mais complexas.
Opção 4: execute Systemd como PID 1 em um namespace/contêiner PID
Finalmente, é possível executar o Systemd no WSL2 (mas não no WSL1). Este é um tópico bastante avançado, embora existam vários scripts e projetos que tentam simplificá-lo.
Avisos: Systemd altera fundamentalmente muitos aspectos do Ubuntu quando iniciado, incluindo a maneira como os soquetes X, login, WSL Interop, arquivos temporários e muito mais! Devido à natureza de VM compartilhada do WSL2, algumas dessas alterações podem até afetar outras distribuições que você está usando sem o Systemd.
Minha recomendação pessoal é (a) certificar-se de que você entende o que está acontecendo nos bastidores se você usar uma dessas técnicas, (b) não faça isso!, ou (c) pelo menos, ao perguntar perguntas sobre por que algo não funciona, certifique-se de informar às pessoas que você está usando um script auxiliar do Systemd no WSL (e qual).
Com isso fora do caminho...
Vamos começar com alguns dos projetos mais populares para habilitar o Systemd no WSL:
Eu pessoalmente não executo nenhum deles regularmente, mas todos são de código aberto, e eu escaneei a fonte para comparar as técnicas. No núcleo, cada um cria um novo namespace ou contêiner onde o Systemd pode ser executado como PID 1.
Você pode ver isso em ação seguindo as etapas:
Corre:
Isso inicia o Systemd em um novo namespace com seu próprio mapeamento PID. Dentro desse namespace, Systemd será PID1 (como deve, para funcionar) e possuirá todos os outros processos. No entanto, o mapeamento PID "real" ainda existe fora desse namespace.
Observe que esta é uma linha de comando "mínimo" para iniciar o Systemd. Não terá suporte para, pelo menos:
.exe
)Os scripts e projetos listados acima fazem um trabalho extra para que essas coisas funcionem também.
Aguarde alguns segundos para que o Systemd seja inicializado e, em seguida:
Isso entra no namespace e agora você pode usar
ps -efH
para ver sesystemd
está sendo executado como PID 1 nesse namespace.Neste ponto, você deve ser capaz de executar
systemctl
.E depois de provar a si mesmo que é possível, recomendo sair completamente de todas as instâncias do WSL e, em seguida, fazer
wsl --shutdown
. Caso contrário, você terá algumas coisas "quebradas" até que você o faça. Eles provavelmente podem ser "consertados", mas isso está além do escopo de qualquer pergunta do Pergunte ao Ubuntu ;-). Minha recomendação é consultar os projetos acima para ver como eles lidam com isso.Nota de rodapé 1 - Snap
Existem certos aplicativos e funções no Ubuntu que são tão complexos que dificilmente serão desembaraçados do Systemd. O exemplo mais óbvio aqui seria o sistema Snap. Tenho certeza de que é teoricamente possível que uma versão do sistema Snap possa ser criada sem o uso do Systemd. No entanto, existem duas boas razões pelas quais isso não acontecerá (em breve, pelo menos):
Snap é um sistema criado e suportado pela Canonical.
A Canonical selecionou o Systemd como o sistema de inicialização do Ubuntu. Só porque o WSL não o suporta (facilmente) não muda isso. Os desenvolvedores da Canonical escreveram o sistema Snap com a expectativa de que a funcionalidade do Systemd estivesse presente.
Atualmente, não parece haver nenhum desejo de terceiros de portar o Snap para distribuições que não sejam do Systemd. Essas distribuições normalmente utilizam o Flatpak no lugar do Snap. Deve-se notar, no entanto, que mesmo o Flatpak tende a utilizar o Systemd em distribuições onde está disponível. No entanto, o Flatpak também está disponível para distribuições que não são do Systemd.
Nota de rodapé 2 - Gnomo
O Gnome também é um aplicativo (ecossistema) que é fortemente acoplado ao Systemd, mas é popular o suficiente para que haja portas para sistemas init não Systemd. Dito isso, executá-lo no Ubuntu pressupõe a presença do Systemd, então você teria que fazer engenharia reversa do processo usado nessas outras distribuições se quisesse executá-lo no Ubuntu/WSL sem o uso do Systemd.
Nota de rodapé 3 - Outros aplicativos dependentes do Systemd
Há também casos em que certos softwares esperam o Systemd e simplesmente não funcionam (ou pelo menos não totalmente) se não estiverem presentes. Um que me deparei recentemente é o Cockpit .
Embora eu tenha conseguido colocá-lo em funcionamento sem o Systemd, ele espera que o Systemd esteja presente para executar muitas, se não a maioria, funções. Na verdade, partes do Cockpit são um front-end para o Systemd.
Esse tipo de software, que executa comandos do Systemd (como
systemctl
), pode ser a exceção à regra "há uma alternativa".Ok, minha resposta pode não estar relacionada à pergunta, mas eu tive um problema semelhante. Eu queria inicializar um Nginx com "sudo systemctl start nginx", mas não funcionou no Ubuntu WSL. Mas descobri que o comando "sudo service nginx start" faz exatamente a mesma coisa. Ele pode inicializar o Nginx sem chamar "systemctl"