为什么需要在运行.sh文件之前放sh?


16

当我想.sh在终端中运行文件时,需要放在文件sh前面。

有什么办法可以避免这种情况,从而节省输入?


3
我在〜/ bin处创建了一个文件夹,以将我的shell脚本放入$ PATH,并将文件夹动作附加到〜/ bin文件夹中,以自动设置执行权限,因为这样做很容易忘记。
凯德尔2013年

Answers:


22

如果您是从shell运行脚本,则实际上不需要此答案中#!/bin/sh概述的shebang –我使用的所有类似Unix的系统(包括OS X)都将默认为如果未特别指定解释器(但这是一个好主意,因为除非您提供了Shebang,否则非shell不会知道如何执行脚本。)/bin/sh

您也不需要.sh扩展。您确实需要设置可执行权限,例如

$ chmod +x script.sh

(这$是shell提示符;我用它来说明您提供给交互式shell的命令。请不要键入它!)

但是,我认为您的困惑是您已经script.sh在当前目录中创建了一个脚本,例如,并尝试通过简单地键入来执行它script.sh。例如

$ cat >script.sh
echo hello, world
^D
$ chmod +x script.sh
$ script.sh
-bash: script.sh: command not found

^D意味着control- D。在使用Unix的许多文章中,您都会找到此表示法。)

事实上,script.sh在这种情况下是一个shell脚本只是问题的一半; 您的实际问题是,默认情况下,shell不会在当前目录中搜索程序。但是,这可行:

$ sh script.sh
hello, world

因为sh是以脚本作为参数。

通过指定要在当前目录中运行一个脚本,可以在当前目录中执行脚本(或者再次是任何可执行文件)(如果标记为可执行文件,即chmod +x)。

$ ./script.sh
hello, world

您也可以将脚本移动到上的目录PATH/usr/local/bin如果您打算在系统范围内使用脚本,那么我建议这样做;如果bin脚本仅适合您,则建议在您家中使用目录。后者要求$HOME/binPATH通过.profile在主目录中的以下行中添加,从而扩展到新的bin目录。

PATH=$HOME/bin:$PATH
export PATH

最后,如果需要,您可以实际将当前目录添加到PATH,这将使您可以转到包含(script.sh或任何其他可执行文件)的目录并键入

$ script.sh

执行它。但是,我不建议您采用这种做法,因为攻击者现在可以通过将可执行脚本(命名为ls)放到您要进入的目录中,以欺骗您运行任意可执行文件。但是,如果您确实想这样做,只需将以下内容添加到您的.profile

PATH=.:$PATH
export PATH

放在 '。' 在$ PATH的末尾而不是开头,现在您不必担心幻影“ ls”。(尽管有人可以进入您的系统,但您遇到的问题更大。)
TJ Luoma 2013年

2
@TJ,但是您确实需要担心诸如slor llsl...之类的问题。刚刚离开.的了$PATH。另外,您可能(或不应该)一定信任系统中的每个人。例如,假设有一些利用程序,使攻击者可以将任意文件拖放到某个目录中,但是他们需要执行该文件才能升级为更好的利用程序(例如,收集数据和电话回家)。纵深防御!
Reid 2013年

@TJLuoma @Reid说了什么,还要记住,除了个人OS X桌面之外,Unix系统还有许多用例。还没有尝试过,但是我敢打赌,来宾帐户也可以将其中一项放在/tmp其他可写在世界上的目录中。
zigg 2013年

如果您使用的系统中其他人可以访问您使用的目录,那么您将遇到更大的问题。
TJ Luoma 2013年

@TJLuoma那么,最好不要在任何Unix系统上使用多个帐户。 /tmp等。随领土而来。
zigg 2013年

10

sh如果脚本文件被标记为可执行文件,则无需调用。在这种情况下,您可以像使用现有Shell中的任何其他命令一样将其命名为我的名字。


为了完全正确,您需要做两件事:

  1. 编辑脚本,在脚本顶部包含shebang指令:

    #!/bin/sh

    ...这将告诉shell使用哪个解释器来运行脚本;在这种情况下,/bin/sh可执行文件。

  2. 使用chmod命令将脚本标记为可执行文件

    chmod u+x scriptname.sh

两者都完成后,您应该能够通过在命令行上键入脚本的文件名来运行脚本。除非您还执行将包含文件夹添加到PATH变量的添加步骤,否则您将需要与脚本位于同一目录中。如果您不在乎运行脚本的外壳程序,则无需指定第一步,sh但是精确起来并设置“ shebangsh”通常会更好。


Shebang实际上并不是必需的/bin/sh,尽管它们不会受到伤害。
zigg 2013年

@zigg-你是正确的。我希望克里斯不介意我的编辑…按要求进行
核对

@bmike编辑对我有用。至于shebang,我的习惯是始终指定,因为我曾经ksh在HP-UX上写过很多脚本,但是很高兴知道这不是绝对必要的。
克里斯·瑞

1
我想我需要放弃之前关于shebang必要性的声明(尽管我的其余回答仍然成立。)您可以从shell运行无shebang的脚本,但是如果使用execsyscall,则会得到ENOEXEC(exec格式错误)。抱歉,@ bmike,@ ChrisW.Rea。我现在去编辑我的答案。
zigg 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.