sudo: source: comando não encontrado

54

Estou atualizando alguns dos perfis padrão para o bash e, a partir dos tutoriais que eu estava seguindo, era possível recarregar o novo perfil com as novas configurações de ambiente usando:

source /etc/bash.bashrc

A única coisa é - as novas variáveis ​​de ambiente estavam disponíveis apenas para o meu usuário atual - e foram ignoradas quando usei o sudo. Eles só ficaram disponíveis para o sudo quando fechei minha sessão do terminal e voltei.

Quando tento usar:

sudo source /etc/bash.bashrc

Eu recebo o erro:

sudo: source: command not found

Existe uma maneira simples de carregar as novas configurações do perfil do bash para o sudo sem precisar fechar o terminal e reiniciar?

- Inicialmente, eu estava usando alguns scripts de instalação que faziam referência às variáveis. Descobri que, embora eles pudessem acessar as variáveis ​​quando chamei os scripts diretamente (embora isso causasse um problema posterior na criação de diretórios, pois eu precisava ser root), chamar os scripts de instalação usando o sudo não.

Eu provei isso testando com estes comandos simples:

echo $ENV_VARIABLE
sudo echo $ENV_VARIABLE

O primeiro produziria o valor da variável, mas o segundo não produziria nada.

HorusKol
fonte
Como você tentou usar as variáveis ​​do sudo? Observe que se você usar o "comando sudo $ variable", ele substituirá a variável do seu shell, não do ambiente do sudo.
João Pinto

Respostas:

72

O problema é que sourceé um comando bash build-in (não um programa - como lsou grep). Eu acho que uma abordagem é fazer login como root e, em seguida, executar o comando source.

sudo -s
source /etc/bash.bashrc
Marcos Roriz Junior
fonte
3
Você está certo que o problema é que sourceé um shell embutido. sudo sué uma maneira estranha de dizer isso - é melhor dizer sudo -squal é a maneira do sudo de dizer "inicie um shell como esse usuário". Sua versão de uma linha não funcionará porque cada um dos comandos nela é executado pelo shell do usuário principal em um subprocesso separado.
poolieby
11
Direito. Além disso, o BASH lê / etc / bashrc na hora do login. Portanto, você também pode usar 'su' com a opção -, -l ou --login para obter o ambiente desse usuário: 'sudo su -' para se tornar root ou 'su - $ username' para se tornar outro usuário.
O exemplo "uma linha" não funcionará porque suinicia um novo shell e a "origem" é executada somente após o término. O primeiro exemplo funciona apenas se a segunda linha usada dentro do shell raiz.
loevborg
sudo -snão é melhor que sudo su. Não terá nenhum efeito de qualquer maneira.
loevborg
11
sudo -stem um efeito semelhante ao iniciar um shell, mas para mim parece deselegante empilhar dois comandos "se tornar outro usuário" quando alguém o faria.
poolieby
14

O problema não é que sourceseja um comando interno do shell. O fato de ser isso é o que realmente está lançando o command not founderro, mas isso não significa que funcionaria se fosse.

O problema real é como as variáveis ​​de ambiente funcionam. E eles funcionam assim: toda vez que um novo processo é iniciado, se nada acontecer, ele herda o ambiente de seu pai. Devido a isso, usar um subshell (por exemplo, digitar bashdentro de uma instância do bash) e observar a saída de envdeve fornecer resultados semelhantes aos de seu pai.

No entanto, devido ao modo como sudofunciona (como indicado em sua página de manual), o sudo tenta remover o ambiente do usuário e criar um ambiente "padrão" para o usuário suplente, para que a execução do comando seja executada como se o usuário que o invocou tivesse foi o usuário que chama (que é o comportamento esperado) e, portanto, executa o nautilus, como sudo nautilusdeve abrir uma pasta na /rootpasta, e não /home/yourusername.

Assim:

Fazendo algo como sudo source script.she sudo command, mesmo que funcionasse, não seria bem-sucedido em definir qualquer variável para a posterior sudo command.

Para passar variáveis ​​de ambiente, você pode dizer ao sudo para preservar o ambiente (por meio do -Eswitch; e ter permissões apropriadas no arquivo sudoers) e / ou configurá-lo para o comando como sudo VAR1=VALUE1 VAR2=VALUE2 command.

ssice
fonte
4

Usando a substituição do processo bash , você pode:

source <(sudo cat /etc/bash.bashrc)
TomDotTom
fonte
11
Como isso ajudaria a iniciar um shell raiz com as novas configurações, que é o que o OP está procurando fazer?
muru 30/07/19
11
O OP estava realmente perguntando como "... recarregar o novo perfil ..." de um shell que precisa ser usado sudopara acessar o perfil. O acima exposto fornece um meio de importar o perfil, evitando o sudo: source: command not foundproblema mencionado.
TomDotTom 03/08/19
"A única coisa é - as novas variáveis ​​de ambiente estavam disponíveis apenas para o meu usuário atual - e foram ignoradas quando usei o sudo."
Muru
3

Como Marcos diz , seu principal problema aqui é que sourceé um comando interno do shell que afeta apenas o processo do shell em que é executado.

A solução mais fácil é iniciar um novo shell como root e o bash será lido automaticamente /etc/bash.bashrcquando for iniciado. Isso é tão simples quanto dizer

sudo bash
poolie
fonte
2

Fechar e reabrir o terminal não deve mudar as coisas. Por padrão, o sudo retira o ambiente. Para desativar isso, adicione -E ao sudo.

psusi
fonte
2

O erro ocorre porque o binário que você está tentando chamar da linha de comando é apenas parte da variável PATH do usuário atual, mas não faz parte do PATH do usuário raiz.

Você pode verificar isso localizando o caminho do binário que você está tentando acessar. No meu caso, eu estava tentando chamar "bettercap-ng". Então eu corri,

$ which bettercap-ng
/home/user/work/bin/bettercap`

Eu verifiquei se esse local faz parte do PATH do meu usuário root.

$ sudo env | grep ^PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

Portanto, o sudo não consegue encontrar o binário que estou tentando chamar na linha de comando. Portanto, retorna o comando de erro não encontrado.

Você pode direcionar o sudo para usar o PATH do usuário atual ao chamar um binário como abaixo.

sudo -E env "PATH=$PATH" [command] [arguments]

De fato, pode-se criar um apelido:

alias mysudo='sudo -E env "PATH=$PATH"'

Também é possível nomear o próprio apelido sudo, substituindo o sudo original.

Ornitorrinco Anônimo
fonte