如何在命令行中从脚本运行函数?

Posted

技术标签:

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

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

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

这样的?

myScript.sh func()

【问题讨论】:

【参考方案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>...

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

【讨论】:

以上是关于如何在命令行中从脚本运行函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Linux 中从 C 执行 shell 脚本?

如何在自定义 PHP 脚本中调用 WordPress 函数

在 argparse 中从变量而不是命令行获取值

如何在同一命令行中的文件上执行 python 脚本? [复制]

如何在命令行中使用选项创建 android 模拟器?

mysql中如何在命令行中,执行一个SQL脚本文件?