如何在命令行中从脚本运行函数?
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】:简单地说,没有。
您可以使用source
(help 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>...
我在接受的解决方案中遇到的一个问题是,当在另一个脚本中采购包含函数的脚本时,后者的参数将由前者评估,从而导致错误。
【讨论】:
以上是关于如何在命令行中从脚本运行函数?的主要内容,如果未能解决你的问题,请参考以下文章