【问题标题】:Whats the difference between running a shell script as ./script.sh and sh script.sh以 ./script.sh 和 sh script.sh 运行 shell 脚本有什么区别
【发布时间】:2011-01-28 21:58:01
【问题描述】:

我有一个看起来像这样的脚本

#!/bin/bash

function something() {
 echo "hello world!!"
}

something | tee logfile 

我已经设置了这个文件的执行权限,当我尝试像这样运行文件时

 $./script.sh

它运行得很好,但是当我像这样在命令行上运行它时

$sh script.sh 

它抛出一个错误。为什么会发生这种情况以及我可以通过哪些方式解决此问题。

【问题讨论】:

    标签: unix scripting shell


    【解决方案1】:

    ./script.sh 运行它将使内核读取第一行(shebang),然后调用 bash 来解释脚本。以sh script.sh 运行它会使用系统默认的sh 的任何shell(在Ubuntu 上这是Dash,它与sh 兼容,但不支持Bash 的一些额外功能)。

    您可以通过将其调用为bash script.sh 来修复它,或者如果它是您的机器,您可以将/bin/sh 更改为bash 而不是当前的任何内容(通常只是通过符号链接-rm /bin/sh && ln -s /bin/bash /bin/sh)。或者你可以使用 ./script.sh 代替,如果这已经工作了;)

    如果您的 shell 确实是 dash 并且您想修改脚本以使其兼容,https://wiki.ubuntu.com/DashAsBinSh 有一个有用的差异指南。在您的示例中,您似乎只需要删除 function 关键字。

    【讨论】:

    • 不是 shell 读取脚本的第一行,而是内核通过其中一个 exec() 系统调用。
    • 更通用一点,内核在脚本的第一行查找 hash-bang 结构并运行在该行命名的解释器(即 shell)(以及跟在口译员后面)。 OP 指定 hash-bang 是 #!/bin/bash,所以内核启动 bash。同样,OP 指定文件是可执行的,path/to/script.sh 需要,但sh script.sh 不需要。
    【解决方案2】:

    如果您的脚本在您当前的工作目录中并且您发出./script.sh,内核将读取shebang(第一行)并执行定义的shell解释器。你也可以通过指定解释器的路径来调用你的script.sh,例如

    /bin/bash myscript.sh
    /bin/sh myscript.sh  
    /bin/ksh myscript.sh etc 
    

    顺便说一句,你也可以这样放你的shebang(如果你不想指定完整路径)

    #!/usr/bin/env sh
    

    【讨论】:

    • 实际上是内核解释了shebang,而不是shell。
    【解决方案3】:

    sh script.sh 强制脚本在 sh - shell 中执行。

    虽然简单地从命令行启动它会使用你所在的 shell-environemnt。

    请发布错误消息以获得更多答案。

    虽然错误可能是随机的: 第一行 /bin/bash 中指定的路径错误 -- 可能没有安装 bash?

    【讨论】:

    • 由内核决定如何处理以./script.sh 运行的脚本。在几乎所有情况下,如果第一行是 hash-bang 行,内核将启动在该行命名的解释器,并将脚本的路径名作为其下一个参数(在 hash-bang 行提供的任何选项之后)。您可以运行任何 shell(zshdashkshfishtcsh 等)和path/to/script.sh 将使用在 hash-bang 行中指定的解释器。
    最近更新 更多