Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash. Inherit functions scopes

Tags:

scope

bash

уI need a global counter and function which returns numbers one by one. For example I want this script to echo 6,7,8 (but it echo 6,6,6):

#!/bin/bash

port_counter=5

function get_free_port {
    port_counter=$((port_counter + 1))
    echo ${port_counter}
}

function foo {
    echo $(get_free_port)
}

foo
foo
(foo;)&

How can I obtain 6,7,8?

UPDATE: Ok, after chepner's answer I need to specify a little my question. If I need to use get_free_port as variable in foo, I can't use this approach, isn't it? So I can't write

function foo {
    variable=get_free_port # variable=$(get_free_port) was ok, but returns 6,6,6
    echo ${variable}
}

Also foo & - like usages is hardly desirable

like image 610
vdshb Avatar asked Sep 15 '26 18:09

vdshb


2 Answers

You can't modify variables from a subprocess (which is what $(...) runs). You don't need one in this case:

function foo {
    get_free_port
}

However, for the same reason, you cannot call foo from a subshell or background job, either. Neither foo &, (foo), nor (foo)& will update the value of port_counter in the current shell.

If you really need to call get_free_port and capture its output, you'll need to use a temporary file. For example:

foo () {
    get_free_port > some_temp_file
    cat some_temp_file
}

If this is not suitable, you may need to rethink your script's design.

like image 200
chepner Avatar answered Sep 17 '26 21:09

chepner


The below code would give you the desired behavior:

#!/bin/bash

port_counter=5

function get_free_port {
    port_counter=$(( port_counter + 1 ))
    echo ${port_counter}
}

function foo {
    get_free_port 
# $(get_free_port) spawns a subshell and the parent shell variables are not
# available in the subshell.
}

foo #runs fine
foo #runs fine
foo #(foo;)& again spawns a subshell and the parent shell pariables are not available here.
like image 41
sjsam Avatar answered Sep 17 '26 20:09

sjsam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!