0

Looking at the files in my /etc/profile.d directory:

cwellsx@DESKTOP-R6KRF36:/etc/profile.d$ ls -l
total 32
-rw-r--r-- 1 root root   96 Aug 20  2018 01-locale-fix.sh
-rw-r--r-- 1 root root 1557 Dec  4  2017 Z97-byobu.sh
-rwxr-xr-x 1 root root 3417 Mar 11 22:07 Z99-cloud-locale-test.sh
-rwxr-xr-x 1 root root  873 Mar 11 22:07 Z99-cloudinit-warnings.sh
-rw-r--r-- 1 root root  825 Mar 21 10:55 apps-bin-path.sh
-rw-r--r-- 1 root root  664 Apr  2  2018 bash_completion.sh
-rw-r--r-- 1 root root 1003 Dec 29  2015 cedilla-portuguese.sh
-rw-r--r-- 1 root root 2207 Aug 27 12:25 oraclejdk.sh

This is Ubuntu on the "Windows Subsystem for Linux (WSL)".

Anyway the content of oraclejdk.sh is like this:

export J2SDKDIR=/usr/lib/jvm/oracle_jdk8
export J2REDIR=/usr/lib/jvm/oracle_jdk8/jre
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Program Files/WindowsApps/CanonicalGroupLimited.Ubuntu18.04onWindows_1804.2019.522.0_x64__79rhkp1fndgsc:/snap/bin:/usr/lib/jvm/oracle_jdk8/bin:/usr/lib/jvm/oracle_jdk8/db/bin:/usr/lib/jvm/oracle_jdk8/jre/bin
export JAVA_HOME=/usr/lib/jvm/oracle_jdk8
export DERBY_HOME=/usr/lib/jvm/oracle_jdk8/db

I'm pretty sure it's run when the bash shell starts.

My question is, why don't all the *sh files have the x permission bit set? Don't all shell scripts need the x perission bit set in order to be executable?

Please consider me a bit of a novice.

Kusalananda
  • 333,661
ChrisW
  • 103
  • 3

2 Answers2

7

A shell script only needs to be executable if it is to be run as

./scriptname

If it is executable, and if it has a valid #!-line pointing to the correct interpreter, then that interpreter (e.g. bash) will be used to run the script.

If the script is not executable (but still readable), then it may still be run with an explicit interpreter from the command line, as for example in

bash ./scriptname

(if it's a bash script). Note that you would have to know what interpreter to use here as a zsh script might not execute correctly if run with bash, and a bash script likewise would possibly break if executed with sh (just as a Perl script would not work correctly if executed by Python or Ruby).

Some script, as the one you show, are not actually scripts but "dot-scripts". These are designed to be sourced, like

. ./scriptname

i.e. used as an argument to the dot (.) utility, or (in bash),

source ./scriptname

(the two are equivalent in bash, but the dot utility is more portable)

This would run the commands in the dot-script in the same environment as the invoking shell, which would be necessary for e.g. setting environment variables in the current environment. (Scripts that are run as ordinary are run in a child environment, a copy of its parent's environment, and can't set environment variables in, or change the current directory of, their parent shells.)

A dot-script is read by (or "sourced by") the current shell, and therefore do not have to be executable, only readable.

I can tell that the script that you show the contents of is a dot-script since it does not have a #!-line (it does not need one) and since it just exports a bunch of variables.


I believe I picked up the term "dot-script" from the manual for the ksh93 shell. I can't find a more authoritative source for it, but sounds like a good word to use to describe a script that is supposed to be sourced using the . command.

Kusalananda
  • 333,661
  • Also, you can pipe the contents of the script to the interpreter. Such as cat ./scriptname | /bin/bash – Scottie H Aug 27 '19 at 16:52
  • 1
    @ScottieH Yes, you can, but that's inconvenient and may drastically change the way the script is behaving, if it's doing anything relating to reading from its standard input stream. This is not to be recommended as a generic way of running a script. – Kusalananda Aug 27 '19 at 16:53
  • @StephenKitt Not too confusing in this case because I more-or-less knew what source means -- https://superuser.com/questions/46139/what-does-source-do – ChrisW Aug 27 '19 at 16:53
3

Shell scripts require the x permission bit to be set to be able to be executed directly, such as

 ./myscript.sh 

If you create this file and don't chmod +x it, you'll get a permission denied error, as you would expect.

However, let's say that the file didn't have the executable bit set. You would still be able to execute the following, which ultimately would execute the script:

sh ./myscript.sh 

or

 bash ./myscript.sh 

(You can go try it in your terminal - really, you only need read permissions to a file to be able to execute it)

Essentially, if you're providing your own interpreter, eg. sh myscript.sh rather than just having the kernel decide what to do with the file based on the shebang, you don't require that execute bit to be set.

matirko
  • 111
  • 5