96

I am creating a little automated setup script that will modify /etc/profile and $HOME/.profile if some paths are not exported. Then, I'd like to reload these automatically.

I have read that source does this, so I fired up my terminal and entered:

source /etc/profile
source ~/.profile

From the terminal, it didn't output any error.

However, putting these two commands inside the Bash script results in source: not found.

  1. How can I be sure that the script is executed by Bash, even if #!/bin/sh is specified (apparently, it does not guarantee it)?
  2. Why would it say that these two sources cannot be found when they are unmistakably there?

4 Answers 4

125

/bin/sh is not bash. To execute your script with bash, write #!/bin/bash as the first line in your script.

The error source: not found is not dropped, because /etc/profile is not found. It's dropped, because source is not found. source is a Bash built-in function, and you don't execute the script with bash. So it's clear why it is not found. Change the #! line in the script, and it will work.

0
34

Some shells support . instead of source. So you can try something like this

. filename

instead of

source filename

Hope it works

2
  • 4
    This was edited to claim that csh supports . and sh supports source, but that edit was wrong and it has since been rolled back. The reverse is true: csh and tcsh support source, POSIX shells (sh) support ., and some POSIX-style shells (like bash) support both. I'm mentioning this because you had approved the edit and might otherwise wonder why it was rolled back. If you really want to say what the edit said, you can roll back the rollback--though that would make this answer wrong. (If you want this post to be more detailed, I think it would be better to do a new edit.) Dec 6, 2019 at 17:29
  • 1
    this worked for me, but I had to fully qualify the path to filename, so . ./filename instead of just . filename
    – knocte
    Jan 7, 2023 at 8:46
14

1. How can I be sure that the script is executed by Bash, even if #!/bin/sh is specified (apparently, it does not guarantee it)?

To be sure that a script written for sh shell (as in your case - see What is difference between #!/bin/sh and #!/bin/bash?) is executed by Bash, just run the following command:

bash script_name

Thus, you will not get that error anymore.

2. Why would it say that these two sources cannot be found when they are unmistakably there?

It doesn't say that those sourced files are not there. It says that the source command is not found. This is normal, because since you start your script with #!/bin/sh line, your script will run using sh and not bash as you may think. Why is it normal? Because source command is a Bash builtin, but not a sh builtin. To source a file in sh, you should use . (dot). Example:

. /etc/profile
. ~/.profile

Another way is to change the shebang line to #!/bin/bash as chaos said in his answer.

9

See this SO question:

/bin/sh is usually some other shell trying to mimic The Shell. Many distributions use /bin/bash for sh, it supports source. On Ubuntu, though, /bin/dash is used which does not support source. If you cannot edit the script, try to change the shell which runs it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .