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
  • 98,580
  • 191
  • 570
  • 977
  • 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
  • 54,820
  • 8
  • 124
  • 141
myaut
  • 1,411
  • 10
  • 12
  • 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
  • 805
  • 2
  • 10
  • 19
Kevin
  • 756
  • 4
  • 13
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