Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 如何从另一个shell脚本调用一个shell脚本?_Bash_Shell - Fatal编程技术网

Bash 如何从另一个shell脚本调用一个shell脚本?

Bash 如何从另一个shell脚本调用一个shell脚本?,bash,shell,Bash,Shell,我有两个shell脚本,a.sh和b.sh 如何从shell脚本中调用b.sh?有几种不同的方法: 使另一个脚本可执行,添加#/bin/bash行,以及文件到$path环境变量的路径。然后可以将其作为普通命令调用 或者用source命令调用它(别名是),如下所示:source/path/to/script 或者使用bash命令执行它:/bin/bash/path/to/script 第一个和第三个方法将脚本作为另一个进程执行,因此无法访问另一个脚本中的变量和函数。 第二个方法在第一个脚本的进程中

我有两个shell脚本,
a.sh
b.sh


如何从shell脚本中调用
b.sh

有几种不同的方法:

  • 使另一个脚本可执行,添加
    #/bin/bash
    行,以及文件到$path环境变量的路径。然后可以将其作为普通命令调用

  • 或者用
    source
    命令调用它(别名是
    ),如下所示:
    source/path/to/script

  • 或者使用
    bash
    命令执行它:
    /bin/bash/path/to/script

  • 第一个和第三个方法将脚本作为另一个进程执行,因此无法访问另一个脚本中的变量和函数。
    第二个方法在第一个脚本的进程中执行该脚本,并从另一个脚本中提取变量和函数,以便它们可以从调用脚本中使用

    在第二种方法中,如果在第二个脚本中使用
    exit
    ,它也将退出第一个脚本。这在第一种和第三种方法中不会发生。

    请查看此项

    #!/bin/bash
    echo "This script is about to run another script."
    sh ./script.sh
    echo "This script has just run another script."
    

    您可以使用
    /bin/sh
    调用或执行另一个脚本(通过实际脚本):

    产出将是:

     # ./mainscript.sh
     You are login as: root
     Date is: Thu Oct 17 02:56:36 EDT 2013
    
    假设新文件为“/home/satya/app/app_specific_env”,文件内容如下

    #!bin/bash
    
    export FAV_NUMBER="2211"
    
    将此文件引用附加到~/.bashrc文件

    source /home/satya/app/app_specific_env
    
    重新启动机器或重新登录时,请在终端中尝试
    echo$FAV_NUMBER
    。它将输出值


    以防万一,如果您想立即看到效果,请在命令行中输入
    source~/.bashrc

    首先必须包含您调用的文件:

    #!/bin/bash
    . includes/included_file.sh
    
    然后调用函数,如下所示:

    #!/bin/bash
    my_called_function
    

    我一直在寻找的答案是:

    ( exec "path/to/script" )
    
    如前所述,
    exec
    在不创建新进程的情况下替换shell然而,我们可以把它放在子shell中,使用parantesses完成

    编辑:
    实际上,
    (“path/to/script”)
    就足够了。

    只要在终端中添加一行您想要键入的内容即可执行脚本
    e、 g:

    如果要执行的脚本不在同一目录中,只需使用脚本的完整路径。
    e、 g.:`/home/user/script目录//myscript.sh&

    取决于。 简要地。。。 如果希望在当前控制台上加载变量并执行,可以在代码中使用
    源myshellfile.sh
    。例如:

    !#/bin/bash
    set -x
    echo "This is an example of run another INTO this session."
    source my_lib_of_variables_and_functions.sh
    echo "The function internal_function() is defined into my lib."
    returned_value=internal_function()
    echo $this_is_an_internal_variable
    
    set +x
    
    如果您只想执行一个文件,而唯一让您感兴趣的是结果,您可以执行以下操作:

    !#/bin/bash
    set -x
    ./executing_only.sh
    sh i_can_execute_this_way_too.sh
    bash or_this_way.sh
    set +x
    
    我希望能帮助你。
    谢谢。

    有几种方法可以做到这一点。要执行脚本的终端:

    #!/bin/bash
    SCRIPT_PATH="/path/to/script.sh"
    
    # Here you execute your script
    "$SCRIPT_PATH"
    
    # or
    . "$SCRIPT_PATH"
    
    # or
    source "$SCRIPT_PATH"
    
    # or
    bash "$SCRIPT_PATH"
    
    # or
    eval '"$SCRIPT_PATH"'
    
    # or
    OUTPUT=$("$SCRIPT_PATH")
    echo $OUTPUT
    
    # or
    OUTPUT=`"$SCRIPT_PATH"`
    echo $OUTPUT
    
    # or
    ("$SCRIPT_PATH")
    
    # or
    (exec "$SCRIPT_PATH")
    

    所有这些对于带有空格的路径都是正确的

    简单的源代码将帮助您。 例如


    从其他文件导入函数时出现一些问题。
    首先:无需执行此文件。最好不要这样做! 加上

    . file
    
    导入所有函数。所有这些都将如同在您的文件中定义一样。
    Second:您可以使用相同的名称定义函数。它将被覆盖。这很糟糕。你可以这样申报

    declare -f new_function_name=old_function_name 
    
    只有在那之后,你才能进口。 因此,您可以用新名称调用旧函数。
    第三个:只能导入文件中定义的函数的完整列表。 如果不需要一些,你可以取消它们。但如果在取消设置后重写函数,它们将丢失。但如果您如上所述设置了对它的引用,则可以在取消设置后使用相同的名称进行恢复。
    最后在普通的进口程序中是危险的,并不是那么简单。小心!您可以编写脚本来更轻松、更安全地执行此操作。 如果只使用部分函数(而不是全部函数),最好将它们拆分到不同的文件中。不幸的是,这种技术在bash中没有得到很好的应用。例如,在python和其他一些脚本语言中,它既简单又安全。可以只使用自己的名称进行部分导入所需的函数。我们都希望,在下一个布什版本将做同样的功能。但现在我们必须写许多额外的cod,以便做你想做的事

    chmod a+x /path/to/file-to-be-executed
    
    那是我唯一需要的。一旦要执行的脚本可以这样执行,您(至少在我的情况下)在调用脚本时不需要任何其他额外的操作,如
    sh
    /


    感谢@Nathan Lilienthal的评论,上面的答案建议添加
    #/bin/bash
    行到正在调用的子脚本的第一行。但即使添加shebang,在子shell中运行脚本并捕获输出也要快得多:

    $(源脚本\u名称)

    当您希望继续运行相同的解释器(例如,从bash到另一个bash脚本)并确保子脚本的shebang行不被执行时,这种方法就起作用了

    例如:

    #!/bin/bash
    SUB_SCRIPT=$(mktemp)
    echo "#!/bin/bash" > $SUB_SCRIPT
    echo 'echo $1' >> $SUB_SCRIPT
    chmod +x $SUB_SCRIPT
    if [[ $1 == "--source" ]]; then
      for X in $(seq 100); do
        MODE=$(source $SUB_SCRIPT "source on")
      done
    else
      for X in $(seq 100); do
        MODE=$($SUB_SCRIPT "source off")
      done
    fi
    echo $MODE
    rm $SUB_SCRIPT
    
    输出:

    ~ ❯❯❯ time ./test.sh
    source off
    ./test.sh  0.15s user 0.16s system 87% cpu 0.360 total
    
    ~ ❯❯❯ time ./test.sh --source
    source on
    ./test.sh --source  0.05s user 0.06s system 95% cpu 0.114 total
    

    *例如,当病毒或安全工具在设备上运行时,执行新进程可能需要额外的100毫秒。

    使用backticks

    $ ./script-that-consumes-argument.sh `sh script-that-produces-argument.sh`
    

    然后获取生产者脚本的输出作为使用者脚本上的参数。

    如果同一目录中有另一个文件,则可以执行以下操作之一:

    bash another_script.sh
    


    使用
    bash
    而不是
    source
    时,脚本无法更改父脚本的环境。
    命令是POSIX标准,而
    source
    命令是
    的可读性更强的bash同义词(我更喜欢
    source
    而不是
    )。如果脚本驻留在其他地方,只需提供该脚本的路径。相对路径和完整路径都应该有效。

    这对我来说是有效的,这是执行另一个的主sh脚本的内容

    #!/bin/bash 
    source /path/to/other.sh
    

    你能给出一些细节吗:哪些操作系统和哪些shell,或者你只是在谈论这个问题
    #!/bin/bash
    SUB_SCRIPT=$(mktemp)
    echo "#!/bin/bash" > $SUB_SCRIPT
    echo 'echo $1' >> $SUB_SCRIPT
    chmod +x $SUB_SCRIPT
    if [[ $1 == "--source" ]]; then
      for X in $(seq 100); do
        MODE=$(source $SUB_SCRIPT "source on")
      done
    else
      for X in $(seq 100); do
        MODE=$($SUB_SCRIPT "source off")
      done
    fi
    echo $MODE
    rm $SUB_SCRIPT
    
    ~ ❯❯❯ time ./test.sh
    source off
    ./test.sh  0.15s user 0.16s system 87% cpu 0.360 total
    
    ~ ❯❯❯ time ./test.sh --source
    source on
    ./test.sh --source  0.05s user 0.06s system 95% cpu 0.114 total
    
    $ ./script-that-consumes-argument.sh `sh script-that-produces-argument.sh`
    
    bash another_script.sh
    
    source another_script.sh
    
    . another_script.sh
    
    #!/bin/bash 
    source /path/to/other.sh