Why source (or dot command) doesn't require the file to be executable
From running help .
or help source
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
From my point of view, it seems like the dot command (or the source
command) is simply running a shell script in the current shell context (instead of spawning another shell).
Question: why doesn't .
(or source
) requires the file to be executable like when you run a normal script?
shell-script shell
add a comment |
From running help .
or help source
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
From my point of view, it seems like the dot command (or the source
command) is simply running a shell script in the current shell context (instead of spawning another shell).
Question: why doesn't .
(or source
) requires the file to be executable like when you run a normal script?
shell-script shell
1
why should it? when making a question like this, it would help if you explain why you find the behavior surprising. Otherwise, the same could be asked: why aren't C source file executables? etc.
– Uncle Billy
9 hours ago
This behavior is surprising to me because normally running a shell script as in./ script
requires the script to be executable.
– Tran Triet
9 hours ago
@UncleBilly So that you don't accidentally type. ~/.bash_history
instead of. ~/.bash_profile
, for example? twitter.com/munificentbob/status/1091220194020622336
– Joker_vD
7 hours ago
add a comment |
From running help .
or help source
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
From my point of view, it seems like the dot command (or the source
command) is simply running a shell script in the current shell context (instead of spawning another shell).
Question: why doesn't .
(or source
) requires the file to be executable like when you run a normal script?
shell-script shell
From running help .
or help source
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
From my point of view, it seems like the dot command (or the source
command) is simply running a shell script in the current shell context (instead of spawning another shell).
Question: why doesn't .
(or source
) requires the file to be executable like when you run a normal script?
shell-script shell
shell-script shell
asked 11 hours ago
Tran TrietTran Triet
1128
1128
1
why should it? when making a question like this, it would help if you explain why you find the behavior surprising. Otherwise, the same could be asked: why aren't C source file executables? etc.
– Uncle Billy
9 hours ago
This behavior is surprising to me because normally running a shell script as in./ script
requires the script to be executable.
– Tran Triet
9 hours ago
@UncleBilly So that you don't accidentally type. ~/.bash_history
instead of. ~/.bash_profile
, for example? twitter.com/munificentbob/status/1091220194020622336
– Joker_vD
7 hours ago
add a comment |
1
why should it? when making a question like this, it would help if you explain why you find the behavior surprising. Otherwise, the same could be asked: why aren't C source file executables? etc.
– Uncle Billy
9 hours ago
This behavior is surprising to me because normally running a shell script as in./ script
requires the script to be executable.
– Tran Triet
9 hours ago
@UncleBilly So that you don't accidentally type. ~/.bash_history
instead of. ~/.bash_profile
, for example? twitter.com/munificentbob/status/1091220194020622336
– Joker_vD
7 hours ago
1
1
why should it? when making a question like this, it would help if you explain why you find the behavior surprising. Otherwise, the same could be asked: why aren't C source file executables? etc.
– Uncle Billy
9 hours ago
why should it? when making a question like this, it would help if you explain why you find the behavior surprising. Otherwise, the same could be asked: why aren't C source file executables? etc.
– Uncle Billy
9 hours ago
This behavior is surprising to me because normally running a shell script as in
./ script
requires the script to be executable.– Tran Triet
9 hours ago
This behavior is surprising to me because normally running a shell script as in
./ script
requires the script to be executable.– Tran Triet
9 hours ago
@UncleBilly So that you don't accidentally type
. ~/.bash_history
instead of . ~/.bash_profile
, for example? twitter.com/munificentbob/status/1091220194020622336– Joker_vD
7 hours ago
@UncleBilly So that you don't accidentally type
. ~/.bash_history
instead of . ~/.bash_profile
, for example? twitter.com/munificentbob/status/1091220194020622336– Joker_vD
7 hours ago
add a comment |
2 Answers
2
active
oldest
votes
Lets say I have a shell script (my-script.sh
)starting with:
#!/bin/sh
If the script has execute permissions set then I can run the script with:
./my-script.sh
In this case you are ultimately asking the kernel to run my-script.sh
as a program, and the kernel (program loader) will check permissions first, and then use /bin/sh ./my-script.sh
to actually execute your script.
But the shell (/bin/sh
) does not care about execute permissions and doesn't check them. So if you call this ...
/bin/sh ./my-script.sh
... The kernel is never asked to run my-script.sh
as a program. The kernel (program loader) is only asked to run /bin/sh
. So the execute permissions will never me checked. That is, you don't need execute permission to run a script like this.
To answer your question:
The difference between you calling ./my-script.sh
and . ./my-script.sh
inside another script is exactly the same. In the first, you are asking the kernel to run it as a program, in the second, you are asking your current shell to read commands from the script and the shell doesn't need (or care about) execute permissions to do this.
Further reading:
Running scripts as programs is surprising behaviour when you think about it. They are not written in machine code. I would read up on why this works; start with reading up on the shebang (#!
) https://en.wikipedia.org/wiki/Shebang_(Unix)
Running scripts with the dot notation is necessary to share variables. All other mechanisms for running start a new shell "context", meaning that any variables set in the called script will not be passed back to the calling script. Bash documentation is a little lite, but it's here: https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html
1
When sourced, then$0
is your bash. If the script is executed, then$0
is./my-script.sh
.
– Freddy
10 hours ago
Thank you very much. Your answer surprises me by the fact that I could run/bin/bash non-executable-file
.
– Tran Triet
10 hours ago
1
@Philip Couling When sourced withsource my-script.sh
or. my-script.sh
.
– Freddy
10 hours ago
@Freddy much clearer. Thanks.
– Philip Couling
10 hours ago
2
@TranTriet Also be aware that running a script withbash ./my-script.sh
or. ./my-script.sh
, the shebang (#!/bin/sh
) will be completely ignored. This can be a problem when crossing between different shells.
– Philip Couling
10 hours ago
|
show 2 more comments
When you say source script.sh
or . script.sh
you are never executing the script. What you are running is a shell command source
which does something. This "something" includes reading from script.sh and executing what-has-been-read. Your script needs to be readable for this. No need for executability.
The behaviour is similar to running bash non-executable-script.sh
or python non-executable-script.py
etc.
New contributor
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f501329%2fwhy-source-or-dot-command-doesnt-require-the-file-to-be-executable%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Lets say I have a shell script (my-script.sh
)starting with:
#!/bin/sh
If the script has execute permissions set then I can run the script with:
./my-script.sh
In this case you are ultimately asking the kernel to run my-script.sh
as a program, and the kernel (program loader) will check permissions first, and then use /bin/sh ./my-script.sh
to actually execute your script.
But the shell (/bin/sh
) does not care about execute permissions and doesn't check them. So if you call this ...
/bin/sh ./my-script.sh
... The kernel is never asked to run my-script.sh
as a program. The kernel (program loader) is only asked to run /bin/sh
. So the execute permissions will never me checked. That is, you don't need execute permission to run a script like this.
To answer your question:
The difference between you calling ./my-script.sh
and . ./my-script.sh
inside another script is exactly the same. In the first, you are asking the kernel to run it as a program, in the second, you are asking your current shell to read commands from the script and the shell doesn't need (or care about) execute permissions to do this.
Further reading:
Running scripts as programs is surprising behaviour when you think about it. They are not written in machine code. I would read up on why this works; start with reading up on the shebang (#!
) https://en.wikipedia.org/wiki/Shebang_(Unix)
Running scripts with the dot notation is necessary to share variables. All other mechanisms for running start a new shell "context", meaning that any variables set in the called script will not be passed back to the calling script. Bash documentation is a little lite, but it's here: https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html
1
When sourced, then$0
is your bash. If the script is executed, then$0
is./my-script.sh
.
– Freddy
10 hours ago
Thank you very much. Your answer surprises me by the fact that I could run/bin/bash non-executable-file
.
– Tran Triet
10 hours ago
1
@Philip Couling When sourced withsource my-script.sh
or. my-script.sh
.
– Freddy
10 hours ago
@Freddy much clearer. Thanks.
– Philip Couling
10 hours ago
2
@TranTriet Also be aware that running a script withbash ./my-script.sh
or. ./my-script.sh
, the shebang (#!/bin/sh
) will be completely ignored. This can be a problem when crossing between different shells.
– Philip Couling
10 hours ago
|
show 2 more comments
Lets say I have a shell script (my-script.sh
)starting with:
#!/bin/sh
If the script has execute permissions set then I can run the script with:
./my-script.sh
In this case you are ultimately asking the kernel to run my-script.sh
as a program, and the kernel (program loader) will check permissions first, and then use /bin/sh ./my-script.sh
to actually execute your script.
But the shell (/bin/sh
) does not care about execute permissions and doesn't check them. So if you call this ...
/bin/sh ./my-script.sh
... The kernel is never asked to run my-script.sh
as a program. The kernel (program loader) is only asked to run /bin/sh
. So the execute permissions will never me checked. That is, you don't need execute permission to run a script like this.
To answer your question:
The difference between you calling ./my-script.sh
and . ./my-script.sh
inside another script is exactly the same. In the first, you are asking the kernel to run it as a program, in the second, you are asking your current shell to read commands from the script and the shell doesn't need (or care about) execute permissions to do this.
Further reading:
Running scripts as programs is surprising behaviour when you think about it. They are not written in machine code. I would read up on why this works; start with reading up on the shebang (#!
) https://en.wikipedia.org/wiki/Shebang_(Unix)
Running scripts with the dot notation is necessary to share variables. All other mechanisms for running start a new shell "context", meaning that any variables set in the called script will not be passed back to the calling script. Bash documentation is a little lite, but it's here: https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html
1
When sourced, then$0
is your bash. If the script is executed, then$0
is./my-script.sh
.
– Freddy
10 hours ago
Thank you very much. Your answer surprises me by the fact that I could run/bin/bash non-executable-file
.
– Tran Triet
10 hours ago
1
@Philip Couling When sourced withsource my-script.sh
or. my-script.sh
.
– Freddy
10 hours ago
@Freddy much clearer. Thanks.
– Philip Couling
10 hours ago
2
@TranTriet Also be aware that running a script withbash ./my-script.sh
or. ./my-script.sh
, the shebang (#!/bin/sh
) will be completely ignored. This can be a problem when crossing between different shells.
– Philip Couling
10 hours ago
|
show 2 more comments
Lets say I have a shell script (my-script.sh
)starting with:
#!/bin/sh
If the script has execute permissions set then I can run the script with:
./my-script.sh
In this case you are ultimately asking the kernel to run my-script.sh
as a program, and the kernel (program loader) will check permissions first, and then use /bin/sh ./my-script.sh
to actually execute your script.
But the shell (/bin/sh
) does not care about execute permissions and doesn't check them. So if you call this ...
/bin/sh ./my-script.sh
... The kernel is never asked to run my-script.sh
as a program. The kernel (program loader) is only asked to run /bin/sh
. So the execute permissions will never me checked. That is, you don't need execute permission to run a script like this.
To answer your question:
The difference between you calling ./my-script.sh
and . ./my-script.sh
inside another script is exactly the same. In the first, you are asking the kernel to run it as a program, in the second, you are asking your current shell to read commands from the script and the shell doesn't need (or care about) execute permissions to do this.
Further reading:
Running scripts as programs is surprising behaviour when you think about it. They are not written in machine code. I would read up on why this works; start with reading up on the shebang (#!
) https://en.wikipedia.org/wiki/Shebang_(Unix)
Running scripts with the dot notation is necessary to share variables. All other mechanisms for running start a new shell "context", meaning that any variables set in the called script will not be passed back to the calling script. Bash documentation is a little lite, but it's here: https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html
Lets say I have a shell script (my-script.sh
)starting with:
#!/bin/sh
If the script has execute permissions set then I can run the script with:
./my-script.sh
In this case you are ultimately asking the kernel to run my-script.sh
as a program, and the kernel (program loader) will check permissions first, and then use /bin/sh ./my-script.sh
to actually execute your script.
But the shell (/bin/sh
) does not care about execute permissions and doesn't check them. So if you call this ...
/bin/sh ./my-script.sh
... The kernel is never asked to run my-script.sh
as a program. The kernel (program loader) is only asked to run /bin/sh
. So the execute permissions will never me checked. That is, you don't need execute permission to run a script like this.
To answer your question:
The difference between you calling ./my-script.sh
and . ./my-script.sh
inside another script is exactly the same. In the first, you are asking the kernel to run it as a program, in the second, you are asking your current shell to read commands from the script and the shell doesn't need (or care about) execute permissions to do this.
Further reading:
Running scripts as programs is surprising behaviour when you think about it. They are not written in machine code. I would read up on why this works; start with reading up on the shebang (#!
) https://en.wikipedia.org/wiki/Shebang_(Unix)
Running scripts with the dot notation is necessary to share variables. All other mechanisms for running start a new shell "context", meaning that any variables set in the called script will not be passed back to the calling script. Bash documentation is a little lite, but it's here: https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html
edited 9 hours ago
answered 11 hours ago
Philip CoulingPhilip Couling
1,066817
1,066817
1
When sourced, then$0
is your bash. If the script is executed, then$0
is./my-script.sh
.
– Freddy
10 hours ago
Thank you very much. Your answer surprises me by the fact that I could run/bin/bash non-executable-file
.
– Tran Triet
10 hours ago
1
@Philip Couling When sourced withsource my-script.sh
or. my-script.sh
.
– Freddy
10 hours ago
@Freddy much clearer. Thanks.
– Philip Couling
10 hours ago
2
@TranTriet Also be aware that running a script withbash ./my-script.sh
or. ./my-script.sh
, the shebang (#!/bin/sh
) will be completely ignored. This can be a problem when crossing between different shells.
– Philip Couling
10 hours ago
|
show 2 more comments
1
When sourced, then$0
is your bash. If the script is executed, then$0
is./my-script.sh
.
– Freddy
10 hours ago
Thank you very much. Your answer surprises me by the fact that I could run/bin/bash non-executable-file
.
– Tran Triet
10 hours ago
1
@Philip Couling When sourced withsource my-script.sh
or. my-script.sh
.
– Freddy
10 hours ago
@Freddy much clearer. Thanks.
– Philip Couling
10 hours ago
2
@TranTriet Also be aware that running a script withbash ./my-script.sh
or. ./my-script.sh
, the shebang (#!/bin/sh
) will be completely ignored. This can be a problem when crossing between different shells.
– Philip Couling
10 hours ago
1
1
When sourced, then
$0
is your bash. If the script is executed, then $0
is ./my-script.sh
.– Freddy
10 hours ago
When sourced, then
$0
is your bash. If the script is executed, then $0
is ./my-script.sh
.– Freddy
10 hours ago
Thank you very much. Your answer surprises me by the fact that I could run
/bin/bash non-executable-file
.– Tran Triet
10 hours ago
Thank you very much. Your answer surprises me by the fact that I could run
/bin/bash non-executable-file
.– Tran Triet
10 hours ago
1
1
@Philip Couling When sourced with
source my-script.sh
or . my-script.sh
.– Freddy
10 hours ago
@Philip Couling When sourced with
source my-script.sh
or . my-script.sh
.– Freddy
10 hours ago
@Freddy much clearer. Thanks.
– Philip Couling
10 hours ago
@Freddy much clearer. Thanks.
– Philip Couling
10 hours ago
2
2
@TranTriet Also be aware that running a script with
bash ./my-script.sh
or . ./my-script.sh
, the shebang (#!/bin/sh
) will be completely ignored. This can be a problem when crossing between different shells.– Philip Couling
10 hours ago
@TranTriet Also be aware that running a script with
bash ./my-script.sh
or . ./my-script.sh
, the shebang (#!/bin/sh
) will be completely ignored. This can be a problem when crossing between different shells.– Philip Couling
10 hours ago
|
show 2 more comments
When you say source script.sh
or . script.sh
you are never executing the script. What you are running is a shell command source
which does something. This "something" includes reading from script.sh and executing what-has-been-read. Your script needs to be readable for this. No need for executability.
The behaviour is similar to running bash non-executable-script.sh
or python non-executable-script.py
etc.
New contributor
add a comment |
When you say source script.sh
or . script.sh
you are never executing the script. What you are running is a shell command source
which does something. This "something" includes reading from script.sh and executing what-has-been-read. Your script needs to be readable for this. No need for executability.
The behaviour is similar to running bash non-executable-script.sh
or python non-executable-script.py
etc.
New contributor
add a comment |
When you say source script.sh
or . script.sh
you are never executing the script. What you are running is a shell command source
which does something. This "something" includes reading from script.sh and executing what-has-been-read. Your script needs to be readable for this. No need for executability.
The behaviour is similar to running bash non-executable-script.sh
or python non-executable-script.py
etc.
New contributor
When you say source script.sh
or . script.sh
you are never executing the script. What you are running is a shell command source
which does something. This "something" includes reading from script.sh and executing what-has-been-read. Your script needs to be readable for this. No need for executability.
The behaviour is similar to running bash non-executable-script.sh
or python non-executable-script.py
etc.
New contributor
New contributor
answered 6 hours ago
MetMet
1212
1212
New contributor
New contributor
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f501329%2fwhy-source-or-dot-command-doesnt-require-the-file-to-be-executable%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
why should it? when making a question like this, it would help if you explain why you find the behavior surprising. Otherwise, the same could be asked: why aren't C source file executables? etc.
– Uncle Billy
9 hours ago
This behavior is surprising to me because normally running a shell script as in
./ script
requires the script to be executable.– Tran Triet
9 hours ago
@UncleBilly So that you don't accidentally type
. ~/.bash_history
instead of. ~/.bash_profile
, for example? twitter.com/munificentbob/status/1091220194020622336– Joker_vD
7 hours ago