22
$ source /etc/environment 

$ sudo source /etc/environment 
[sudo] password for t: 
sudo: source: command not found

It seems that a different shell than bash is run to execute source /etc/environment and that shell doesn't have source as builtin.

But my and the root's default shells are both bash.

$ echo $SHELL
/bin/bash

If sudo indeeds uses a different shell, why is it? I saw slm's reply, but don't understand in my case.

Tim
  • 101,790
  • 5
    source is a shell builtin..you can not use sudo to run a shell builtin like an external command.. – heemayl May 08 '15 at 22:12
  • Is the issue that you cannot read the file, or that you want the environment defined in the file to apply to subsequent sudo commands? – Random832 May 09 '15 at 05:07
  • @Random832: want the environment defined in the file to apply to subsequent sudo commands – Tim May 09 '15 at 13:02

3 Answers3

34

source is a shell builtin, so it cannot be executed without the shell. However, by default, sudo do not run shell. From sudo

Process model

When sudo runs a command, it calls fork(2), sets up the execution environment as described above, and calls the execve system call in the child process

If you want to explicitly execute shell, use -s option:

# sudo -s source /etc/environment

Which is still useless because after shell is exited, environment changes are lost.

heemayl
  • 56,300
myaut
  • 1,431
  • This worked for me. I just ran into an error though which I thought I might share it and its workaround as it might happen to you too. /root: Is a directory. I think it is a common problem when inserting your environment variables using vi or vim. I turned out that the .sh file which I tried to source has a tilde character (" ") at the end of it. By removing it from the file,sudo -s source /etc/environment` worked without no error. – MajidJafari May 28 '20 at 05:42
12

In the realm of solving the problem rather than answering the question, here's the most obvious (to me) way to source a file which only root can read:

source <(sudo cat /etc/environment)

This uses process substitution. It takes the output of the cat command and turns it into a pseudo-file, which you can pass to source. source then runs the commands in the current shell.

Note that on most systems, /etc/environment is world-readable, so you ought to be able to just run this:

source /etc/environment
Glorfindel
  • 815
  • 2
  • 10
  • 19
Kevin
  • 766
2

sudo expects a command but you are giving a shell builtin so it cannot find the command. If you write type source, you can see the output: source is a shell builtin and the output of which source is empty.

For example sudo strace will work and which strace will give output because strace is a command.

Edit: Also, you can see sudo su;sudo source /etc/environment works nicely so different shell is not used.

Esref
  • 553
  • 2
  • 6
  • 17