Answers:
你很困惑 该.sh
扩展名仅是对人类的提示,对系统处理文件的方式完全没有影响。Unix / Linux并没有使Windows Secrets.pdf.exe
大失所望。
这是您输入时发生的事情foo
:
重定向STDIN
,STDOUT
以及STDERR
是否建立。
Shell检查其内部哈希表以查看是否已经知道的$PATH
条目foo
。如果不存在,则外壳程序将搜索中的目录$PATH
,以查找一个名为foo
的文件,该文件的文件许可权中设置了执行位。先foo
赢。
如果文件的前两个字节foo
是#!
,则下一个字符串是要运行的解释器的名称。因此#!/bin/bash
引入了Bash脚本,#!/usr/bin/perl
引入了Perl脚本等。
如果文件以开头\177ELF
,则为二进制可执行文件,然后ld.so
启动它。
阅读man execve
和man ld.so
获得更详细的解释。
chmod +x
)可以解决这个问题,对吗?
x
所有内容)和文件的来源(可以控制目录控制权的任何进程都可以用来设置权限) 。因此,它可以缓解问题,但我不会说它可以解决问题。
Secrets.pdf.exe
因为我总是禁用愚蠢的hide file extension
功能
关键是:扩展与任何类Unix系统都不相关,文件名只是名称,对脚本或编译后的可执行文件是否可以运行没有影响。程序员可以添加.sh
扩展名来指定文件是Shell脚本,还是.py
python脚本,但是与Windows不同,任何unix都不在乎命名,在乎权限。
重要的是授予文件的可执行权限。您可以检查的
ls -l /path/to/file
运行脚本通常有几种方法。
./my_script_name
。该.
指当前目录。/home/user/bin/my_script_name
(以上两种方法都依赖于设置可执行权限;文件是否是$PATH
变量的一部分无关紧要。#!
行的存在也很重要;没有它,脚本将由您打开的当前shell执行。如果我有csh
脚本如果没有该行,请尝试使用运行在bash中./my_script.csh
,它将失败)
$PATH
变量的目录中,则只需调用名称即可运行它。您可以chmod
在命令行中仅通过键入命令名称来调用命令,因为它位于/bin
文件夹中。/bin
始终是$PATH
变量的一部分。在这种情况下,可执行权限和脚本的位置很重要. filename.sh
或source filename.sh
将使脚本被视为键盘输入,即就像直接在命令行中键入一样。在这种情况下,可执行权限和位置无关紧要Example#1(使用解释器运行)具有执行权限
$-> ls -l abc.py
-rw-rw-r-- 1 xieerqi xieerqi 44 Apr 27 22:39 abc.py
$-> python abc.py
a
b
c
Example#2,在./
设置了可执行权限(shebang行)的情况下运行。
$-> cat abc.py
#!/usr/bin/env python
for letter in 'a' 'b' 'c' :
print letter
$-> ls -l abc.py
-rwxrwxr-x 1 xieerqi xieerqi 66 Apr 27 23:02 abc.py*
$-> ./abc.py
a
b
c
示例#3,在没有设置shebang行的情况下运行(失败,因为bash无法读取python脚本;没有shebang行将当前的shell假定为解释器)
$-> cat abc.py
for letter in 'a' 'b' 'c' :
print letter
$-> ./abc.py
./abc.py: 2: ./abc.py: Syntax error: word unexpected (expecting "do")
Example#4,具有可执行权限的运行脚本将form文件夹设置为$PATH
变量的一部分
# /home/xieerqi/bin is part of my path variable
$-> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/microchip/xc16/v1.25/bin:/opt/microchip/xc32/v1.40/bin:/opt/microchip/xc8/v1.35/bin:/home/xieerqi/bin:/home/xieerqi/bin/sh
$-> # current directory is /home/xieerqi
$-> pwd
/home/xieerqi
$-> # move the file to ~/bin
$-> mv ~/abc.py ~/bin/abc.py
$-> # now I can run it just by calling the name
$-> abc.py
/home/xieerqi/bin/abc.py: 2: /home/xieerqi/bin/abc.py: Syntax error: word unexpected (expecting "do")
$-> # Syntax error because again, no interpreter specified.
$-> # must add #!/usr/bin/env python
$-> vi /home/xieerqi/bin/abc.py
$-> # after adding the line with vi text editor, we can run
$-> abc.py
a
b
c
示例#5(删除扩展名)仍然可以运行,因为扩展名无关紧要,但是扩展名具有权限,并且是的一部分$PATH
:
$-> mv ~/bin/abc.py ~/bin/abc
$-> abc
a
b
c
PATH
吗?
man chmod
,看看如何设置权限
这里已经有很好的解释了。我只是想补充一点,理想情况下,您不应该对可执行文件使用文件扩展名。
通常,您需要完成一些相对容易的事情,并从一个小的Shell脚本开始。随着时间的流逝,您开始向脚本中添加越来越多的功能,直到它变得无法维护或者需要一些用shell脚本无法轻松完成的功能,然后考虑用另一种语言重写该shell脚本(python ,perl,...?)。
从头开始重写通常被认为是错误,但是对于脚本来说这可能是有道理的,因为它们通常不大或没有很多功能。但是,让我们假设以某种其他语言从头开始重写,并保持初始shell脚本的功能和params / flags是可行的。
使用此脚本的用户无需了解此语言更改,他们将继续执行相同的命令,它将继续运行。
如果您的脚本被命名为do-something.sh
,它可以继续为do-something.sh
,但是现在它是用python编写的(例如),因此您的最初提示现在完全是一种误导性提示。
要运行不带扩展名的文件,您通常不需要做很多事情,只需确保(在bash脚本的情况下)第一行有适当的shebang行:
#!/bin/bash
那么您还需要通过以下方式使文件对系统可执行:
chmod 755 yourfilename
这与使用chmod +x yourfilename
数字一样容易解释。
它是添加的八进制的数字三倍,第一个数字代表用户,第二个数字代表组,第三个数字代表其他用户,您可以在这里找到更多信息。
而且,如果您与脚本位于同一目录中,请不要忘记使用./
以下命令:
./yourfilename
.sh后缀实际上可能会妨碍您,因为然后运行它,您必须键入myscript.sh而不是仅无法使用myscript。最好不带.sh后缀,将其称为“ myscript”,然后快速使用“ file”命令将告诉您它是二进制可执行文件(在Linux上为ELF格式)还是Shell脚本,或任何其他类型的脚本。
QDOS(Quick and Dirty操作系统,后来在mirosoft盗版并非法出售给他们后,由IBM重命名为“ DOS”)和其他廉价的CP / M盗版,包括Windows,将所有这些混在一起,因为在那些系统上没有例如对文件的执行权限。在过去的30-40年中,这导致了无数的安全问题。其实就在几分钟前,我收到了几封垃圾邮件,它们的诱杀式zip文件重命名为MYPICTURE.JPG.zip :)
.sh
在许多情况下,使用扩展名被认为是不好的做法:与其他命令的命名方式(您不运行ls.elf
)相反,它常常会引起误解(如果foo.sh
以开头#!/bin/bash
,则运行时sh foo.sh
将使用与构建时不同的解释器来运行它),并且如果您将其重写foo.sh
为Python程序,则使用该扩展名意味着您需要在保留误导性的名称和重写每个调用它的程序之间进行选择。