【问题标题】:How can I run a function from a script in command line?如何在命令行中从脚本运行函数?
【发布时间】:2012-02-07 17:46:55
【问题描述】:

我有一个脚本,它有一些功能。

我可以直接从命令行运行其中一个函数吗?

这样的?

myScript.sh func()

【问题讨论】:

    标签: linux bash scripting


    【解决方案1】:

    如果脚本只定义函数而不做其他任何事情,您可以首先使用source. 命令在当前shell 的上下文中执行脚本,然后简单地调用该函数。请参阅help source 了解更多信息。

    【讨论】:

    • 这个方法唯一的问题是,如果你在你的函数中使用exit,它会在函数执行后关闭终端。有没有办法解决? @SvenMarnach
    • @user1527227:在这种情况下使用下一个答案,因为您可以控制 shell 脚本。如果你不这样做,你可以先调用一个交互式子shell(只需输入bash),exit只会终止子shell,而不是你的终端。
    • 如果有一个实际的代码示例会很好
    【解决方案2】:

    以下命令首先在上下文中注册函数,然后调用它:

    . ./myScript.sh && function_name
    

    【讨论】:

    • 你也可以简单地使用source。如 - source myScript.sh && function_name
    • 我可以知道为什么您的替代方案更简单吗?不要刻薄,我真的不明白?
    • 如果用户想将一些命令行参数/选项传递给脚本怎么办?
    【解决方案3】:

    简单地说,没有。

    您可以使用sourcehelp source 了解详细信息)将脚本中的所有函数导入您的环境,然后您可以调用它们。这也有执行脚本的效果,请注意。

    无法像调用共享库一样从 shell 脚本调用函数。

    【讨论】:

    • 我认为这应该作为一个合适的答案给予更多的重视。我试图做一些类似于 OP 想要的事情,但是 shell 脚本根本不是为“干净的、OOP 开发”(恕我直言)而设计的。
    【解决方案4】:

    好吧,虽然其他答案是正确的 - 你当然可以做其他事情:如果你可以访问 bash 脚本,你可以修改它,并简单地将特殊参数 "$@" 放在末尾 - 它将扩展为您指定的命令行的参数,因为它是“单独的”,shell 将尝试逐字调用它们;在这里您可以将函数名称指定为第一个参数。示例:

    $ cat test.sh
    testA() {
      echo "TEST A $1";
    }
    
    testB() {
      echo "TEST B $2";
    }
    
    "$@"
    
    
    $ bash test.sh
    $ bash test.sh testA
    TEST A 
    $ bash test.sh testA arg1 arg2
    TEST A arg1
    $ bash test.sh testB arg1 arg2
    TEST B arg2
    

    对于波兰语,可以先验证命令存在且是函数:

    # Check if the function exists (bash specific)
    if declare -f "$1" > /dev/null
    then
      # call arguments verbatim
      "$@"
    else
      # Show a helpful error
      echo "'$1' is not a known function name" >&2
      exit 1
    fi
    

    【讨论】:

    • 在大多数情况下使用"$@"$@ 在某些情况下并不安全。
    • 如何运行多个函数?例如我可以运行bash test.sh testA testB 吗?
    • 这也需要用[ ! -z "$1" ] 包裹,否则源代码会在某些 bash 版本中引发 else 语句
    • 我一直在四处寻找这个神奇的“$@”变量来使用文件上调用的任何函数,谢谢@sdaau!
    • 如果我在test.sh 开头还有一些不是函数的代码怎么办?它仍然有效吗? - 我试过了,是的,它有效!
    【解决方案5】:

    编辑:警告 - 似乎这并不适用于所有情况,但适用于许多公共脚本。

    如果你有一个名为“control”的 bash 脚本,并且在其中你有一个名为“build”的函数:

    function build() { 
      ... 
    }
    

    然后你可以这样调用它(从它所在的目录):

    ./control build
    

    如果它在另一个文件夹中,那就是它:

    another_folder/control build
    

    如果您的文件名为“control.sh”,则相应地会使函数像这样调用:

    ./control.sh build
    

    【讨论】:

    • 这对我来说在交互式 shell 中不起作用。但这有效:. ./control.sh && build
    【解决方案6】:

    我有一种情况,我需要 bash 脚本中的一个函数,该函数之前不得执行(例如,source),@$ 的问题是 myScript.sh 然后运行了两次,似乎...所以我想出了用 sed 来实现这个功能的想法:

    sed -n "/^func ()/,/^}/p" myScript.sh

    为了在我需要的时候执行它,我把它放在一个文件中并使用source

    sed -n "/^func ()/,/^}/p" myScript.sh > func.sh; source func.sh; rm func.sh

    【讨论】:

      【解决方案7】:

      你可以像下面这样从命令行参数调用函数

      function irfan() {
      echo "Irfan khan"
      date
      hostname
      }
      function config() {
      ifconfig
      echo "hey"
      }
      $1
      

      定义函数后,将 $1 放在末尾以接受要调用的函数的参数。 假设上面的代码保存在 fun.sh 中。现在你可以在命令行中调用 ./fun.sh irfan & ./fun.sh config 之类的函数了。

      【讨论】:

        【解决方案8】:

        使用case

        #!/bin/bash
        
        fun1 () {
            echo "run function1"
            [[ "$@" ]] && echo "options: $@"
        }
        
        fun2 () {
            echo "run function2"
            [[ "$@" ]] && echo "options: $@"
        }
        
        case $1 in
            fun1) "$@"; exit;;
            fun2) "$@"; exit;;
        esac
        
        fun1
        fun2
        

        此脚本将运行函数 fun1 和 fun2 但如果您使用选项启动它 fun1 或 fun2 它只会运行带有 args 的给定函数(如果提供)并退出。 用法

        $ ./test 
        run function1
        run function2
        
        $ ./test fun2 a b c
        run function2
        options: a b c
        

        【讨论】:

          【解决方案9】:

          已解决的帖子,但我想提一下我的首选解决方案。即定义一个通用的单行脚本eval_func.sh:

          #!/bin/bash
          source $1 && shift && "@a"
          

          然后通过以下方式调用任何脚本中的任何函数:

          ./eval_func.sh <any script> <any function> <any args>...
          

          我在接受的解决方案中遇到的一个问题是,当在另一个脚本中采购包含函数的脚本时,后者的参数将由前者评估,从而导致错误。

          【讨论】:

            猜你喜欢
            • 2015-08-27
            • 2019-11-09
            • 1970-01-01
            • 2019-06-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多