简体   繁体   English

如何从命令行中的脚本运行 function?

[英]How can I run a function from a script in command line?

I have a script that has some functions.我有一个具有某些功能的脚本。

Can I run one of the function directly from command line?我可以直接从命令行运行 function 之一吗?

Something like this?是这样的吗?

myScript.sh func()

Well, while the other answers are right - you can certainly do something else: if you have access to the bash script, you can modify it, and simply place at the end the special parameter "$@" - which will expand to the arguments of the command line you specify, and since it's "alone" the shell will try to call them verbatim;好吧,虽然其他答案是正确的-您当然可以做其他事情:如果您可以访问 bash 脚本,则可以对其进行修改,只需在末尾放置特殊参数"$@" -它将扩展为参数在您指定的命令行中,并且由于它是“单独的”,shell 将尝试逐字调用它们; and here you could specify the function name as the first argument.在这里你可以指定函数名作为第一个参数。 Example:例子:

$ 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

For polish, you can first verify that the command exists and is a function:对于波兰语,您可以先验证该命令是否存在并且是一个函数:

# 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

If the script only defines the functions and does nothing else, you can first execute the script within the context of the current shell using the source or .如果脚本只定义函数而不执行其他任何操作,您可以先在当前 shell 的上下文中使用source. command and then simply call the function.命令,然后简单地调用该函数。 See help source for more information.有关更多信息,请参阅help source

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

. ./myScript.sh && function_name

Briefly, no.简而言之,没有。

You can import all of the functions in the script into your environment with source ( help source for details), which will then allow you to call them.您可以将脚本中的所有函数与source (详细信息为help source )一起导入到您的环境中,然后您就可以调用它们了。 This also has the effect of executing the script, so take care.这也有执行脚本的作用,所以要小心。

There is no way to call a function from a shell script as if it were a shared library.无法从 shell 脚本调用函数,就像它是共享库一样。

Using case使用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

This script will run functions fun1 and fun2 but if you start it with option fun1 or fun2 it'll only run given function with args(if provided) and exit.此脚本将运行函数 fun1 和 fun2,但如果您使用选项 fun1 或 fun2 启动它,它将仅运行带有 args(如果提供)的给定函数并退出。 Usage用法

$ ./test 
run function1
run function2

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

I have a situation where I need a function from bash script which must not be executed before (eg by source ) and the problem with @$ is that myScript.sh is then run twice, it seems... So I've come up with the idea to get the function out with sed:我有一种情况,我需要一个来自 bash 脚本的函数,该函数之前不能执行(例如通过source ), @$的问题是 myScript.sh 然后运行两次,似乎......所以我想出了想用 sed 来实现这个功能:

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

And to execute it at the time I need it, I put it in a file and use source :为了在我需要的时候执行它,我把它放在一个文件中并使用source

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

Edit: WARNING - seems this doesn't work in all cases, but works well on many public scripts.编辑:警告 - 似乎这并不适用于所有情况,但适用于许多公共脚本。

If you have a bash script called "control" and inside it you have a function called "build":如果您有一个名为“control”的 bash 脚本,并且在其中有一个名为“build”的函数:

function build() { 
  ... 
}

Then you can call it like this (from the directory where it is):然后你可以这样调用它(从它所在的目录):

./control build

If it's inside another folder, that would make it:如果它在另一个文件夹中,那就是:

another_folder/control build

If your file is called "control.sh", that would accordingly make the function callable like this:如果您的文件名为“control.sh”,则相应地使函数可调用,如下所示:

./control.sh build

Solved post but I'd like to mention my preferred solution.已解决帖子,但我想提一下我的首选解决方案。 Namely, define a generic one-liner script eval_func.sh :即,定义一个通用的单行脚本eval_func.sh

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

Then call any function within any script via:然后通过以下方式调用任何脚本中的任何函数:

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

An issue I ran into with the accepted solution is that when sourcing my function-containing script within another script, the arguments of the latter would be evaluated by the former, causing an error.我在接受的解决方案中遇到的一个问题是,当在另一个脚本中获取我的包含函数的脚本时,后者的参数将由前者评估,从而导致错误。

The other answers here are nice, and much appreciated, but often I don't want to source the script in the session (which reads and executes the file in your current shell) or modify it directly.这里的其他答案很好,非常感谢,但通常我不想在 session 中获取source (它在当前 shell 中读取并执行文件)直接修改它。

I find it more convenient to write a one or two line 'bootstrap' file and run that.我发现编写一两行“引导程序”文件并运行它更方便。 Makes testing the main script easier, doesn't have side effects on your shell session, and as a bonus you can load things that simulate other environments for testing.使测试主脚本更容易,对您的 shell session 没有副作用,作为奖励,您可以加载模拟其他环境的东西进行测试。 Example...例子...

# breakfast.sh
make_donuts() { 
     echo 'donuts!'
}

make_bagels() {
     echo 'bagels!'
}
# bootstrap.sh
source 'breakfast.sh'

make_donuts

Now just run ./bootstrap.sh .Same idea works with your python, ruby, or whatever scripts.现在只需运行 ./bootstrap.sh 。同样的想法适用于您的./bootstrap.sh或任何脚本。

Why useful?为什么有用? Let's say you complicated your life for some reason, and your script may find itself in different environments with different states present.假设您出于某种原因使您的生活变得复杂,并且您的脚本可能会发现自己处于不同的环境中并呈现不同的状态。 For example, either your terminal session, or a cloud provider's cool new thing.例如,您的终端 session,或者云提供商的酷炫新事物。 You also want to test cloud things in terminal, using simple methods.您还想使用简单的方法在终端中测试云事物。 No worries, your bootstrap can load elementary state for you.不用担心,您的引导程序可以为您加载基本的 state。

# breakfast.sh
# Now it has to do slightly different things
# depending on where the script lives!

make_donuts() {
    if [[ $AWS_ENV_VAR ]]
    then
        echo '/donuts'
    elif [[ $AZURE_ENV_VAR ]]
    then
        echo '\donuts'
    else 
        echo '/keto_diet'
    fi
}

If you let your bootstrap thing take an argument, you can load different state for your function to chew, still with one line in the shell session:如果你让你的引导程序发生争论,你可以为你的 function 加载不同的 state 来咀嚼,仍然在 shell session 中有一行:

# bootstrap.sh
source 'breakfast.sh'

case $1 in
    AWS)
        AWS_ENV_VAR="arn::mumbo:jumbo:12345"
    ;;
    AZURE)
        AZURE_ENV_VAR="cloud::woo:_impress"
    ;;
esac

make_donuts # You could use $2 here to name the function you wanna, but careful if evaluating directly.

In terminal session you're just entering: ./bootstrap.sh AWS Result: # /donuts在终端 session 中,您刚刚输入: ./bootstrap.sh AWS结果: # /donuts

you can call function from command line argument like below您可以从命令行参数调用函数,如下所示

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

once you function end put $1 to accept argument let say above code is saved in fun.sh to run function ./fun.sh irfan & ./fun.sh config一旦你函数结束把 $1 接受参数让说上面的代码保存在 fun.sh 中运行函数 ./fun.sh irfan & ./fun.sh config

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM