Anonymous functions in shell scripts

前端 未结 6 1709
無奈伤痛
無奈伤痛 2021-01-03 20:00

Is it possible to create something analogous to an anonymous function whose value can be assigned to an array element and later called? I can\'t seem to find a way to do thi

相关标签:
6条回答
  • 2021-01-03 20:54

    Short answer: No.

    Long answer: Nooooooooooooo.

    Complete answer: Functions in bash are not first-class objects, therefore there can be no such thing as an anonymous function in bash.

    0 讨论(0)
  • 2021-01-03 20:55

    The common technique is to assign function definitions conditionally:

    #!/bin/sh
    
    case $1 in
    a) foo() { echo case a; };;
    b) foo() { echo case b; };;
    *) foo() { echo default; } ;;
    esac
    
    foo
    
    0 讨论(0)
  • 2021-01-03 20:55

    well bash is turing complete, soo thats perfectly possible ;)

    but aside from this its not really worth the consideration.

    you could simulate such behaviour though with something along this line:

    echo myval ; ( foocmd "$_" && barcmd "$_" )
    

    but why?!?

    0 讨论(0)
  • 2021-01-03 20:56

    It is possible; I wrote a library to do exactly this, though it's a very strange project. The source code is available at http://github.com/spencertipping/bash-lambda. Using this library:

    $ my_array=()
    $ my_array[0]=$(fn x 'echo $((x + 1))')
    $ my_array[1]=$(fn x 'echo $((x + 2))')
    $ ${my_array[0]} 5
    6
    $ ${my_array[1]} 5
    7
    $
    

    The trick is to have the fn function create a file containing the body of the function, chmod +x that file, then return its name. This causes stray files to accumulate, which is why the library also implements an asynchronous mark/sweep garbage collector.

    0 讨论(0)
  • 2021-01-03 20:57

    If you really need array to store the functions, you can define named functions and store just their names. You can then call the function as ${array[n]}. Or, you can name them func1 .. funcN and then just call func$n.

    0 讨论(0)
  • 2021-01-03 21:00

    Create the fn file in your PATH

    #!/bin/sh
    
    printusage () {
            printf "Create anonymous function, for example\n"
            printf "fn 'echo "$1 $2"'"
            exit 1
    }
    
    
    [ "$#" = "1" ] || printusage
    fun=$1
    [ "$fun" = "" ] && printusage
    fun_file="$(mktemp /tmp/fun_XXXXXX)"
    
    echo "#!/bin/sh" > "$fun_file"
    echo "" >> "$fun_file"
    echo "$fun" >> "$fun_file"
    chmod u+x "$fun_file"
    
    echo "$fun_file"
    

    You can then do :

    foo=$(fn 'echo $1')
    ${foo} "bar" 
    
    0 讨论(0)
提交回复
热议问题