查看我的目录中的文件/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 决定如何处理文件,您不需要设置执行位。