shell脚本必须是可执行的吗?

shell脚本必须是可执行的吗?

查看我的目录中的文件/etc/profile.d

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

这是“Windows Subsystem for Linux (WSL)”上的 Ubuntu。

无论如何,内容oraclejdk.sh是这样的:

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

我很确定它在 bash shell 启动时运行。

我的问题是,为什么不是所有*sh文件都x设置了权限位?不是所有 shell 脚本都需要x设置权限位才能可执行吗?

请认为我是一个新手。

答案1

shell 脚本仅在要运行时才需要可执行

./scriptname

如果它是可执行的,并且它有一个有效的#!-line 指向正确的解释器,那么该解释器(例如bash)将用于运行该脚本。

如果脚本是不是可执行文件(但仍然可读),那么它仍然可以使用命令行中的显式解释器运行,例如

bash ./scriptname

(如果它是一个bash脚本)。请注意,您必须知道此处使用什么解释器,因为zsh如果使用 运行,脚本可能无法正确执行bash,并且bash如果使用 执行,脚本同样可能会中断sh(就像如果由 Python 或 Ruby 执行,Perl 脚本将无法正常工作) 。

有些脚本,就像你展示的那样,实际上并不是脚本但是“点脚本”。这些设计目的是来源, 喜欢

. ./scriptname

即用作点 ( ) 实用程序的参数.,或(在bash)中,

source ./scriptname

(两者在 中是等效的bash,但 dot 实用程序更便携)

这将在与调用 shell 相同的环境中运行点脚本中的命令,这对于在当前环境中设置环境变量是必要的。 (正常运行的脚本在子环境(其父环境的副本)中运行,并且无法在其父 shell 中设置环境变量或更改其当前目录。)

点脚本由当前 shell 读取(或“源自”),因此不必是可执行的,只需可读。

我可以看出您显示的内容的脚本是一个点脚本,因为它没有 -line #!(它不需要)并且因为它只导出一堆变量。


相信我从 shell 手册中找到了术语“点脚本” ksh93。我找不到更权威的来源,但听起来是一个很好的词来描述应该使用该.命令获取的脚本。

答案2

Shell脚本需要x设置权限位才能直接执行,例如

 ./myscript.sh 

如果您创建此文件并且不对其进行 chmod +x,您将收到权限被拒绝的错误,正如您所期望的那样。

但是,假设该文件没有设置可执行位。您仍然可以执行以下命令,最终将执行脚本:

sh ./myscript.sh 

或者

 bash ./myscript.sh 

(你可以在终端中尝试一下 - 实际上,你只需要文件的读取权限就可以执行它)

本质上,如果您提供自己的口译员,例如。 sh myscript.sh 而不是让内核根据 shebang 决定如何处理文件,您不需要设置执行位。

相关内容