I was using shell scripts and the scripts were getting long and hard to read, so I tried to summarize them with functions.
However, the return values of shell script functions are different from those of functions in other programming languages, and it required some ingenuity to use them in the same way.
However, it has been a bit tricky to use, so I will make a note of how to use it for myself.
Problems with shell script functions
The function can return a return value of return
, but it can only return one integer value.
Rather than a return value, it is used as an exit status value indicating whether the function succeeded or not, and generally returns "0" if the function succeeded.
So how do we pass the information to the function caller, via standard output?
However, since debugging information may be output to standard output, it is necessary to output information as return values and debugging information separately.
Solution (Matching utilization)
We tried to output debugging information to standard error and return value information to standard output.
We have also added the ability to return values via an array so that multiple values can be returned.
#!/bin/bash function test_array { val1=$1 val2=$2 # stderr echo "debug out: val1->${val1}, val2->${val2}" 1>&2 # set return values ret_val=($val1 $val2) # stdout return values echo ${ret_val[@]} # exit status return 0 } res=($(test_array 123 "abc")) echo ${res[0]} echo ${res[1]}
debug out: val1->123, val2->abc 123 abc
Solution (JSON utilization)
If an array is used to return a value, the value will be split by whitespace characters when a string containing whitespace characters is returned.
Therefore, we decided to store the values in JSON and return them.
#!/bin/bash function test_json { val1=$1 val2=$2 # stderr echo "debug out : val1->${val1}, val2->${val2}" 1>&2 # set return values ret_val=$(cat <<_JSON_ [ $val1, "$val2" ] _JSON_ ) # stdout return values echo $ret_val # exit status return 0 } res=$(test_json 123 "abc def") echo $res | jq -r '.[0]' echo $res | jq -r '.[1]'
debug out : val1->123, val2->abc def 123 abc def
Other Comments, etc.
I wanted to write nicely, but I ended up using it in a muddy way.
The reason why the functions have this specification is that, like Linux commands, data output is done by standard output (stream) so that each can be connected by a pipe.
It makes sense, but it would be more productive and convenient if shell scripts could be written like modern programming languages, not just function writing.
There seems to be a demand for writing such shell scripts in a modern style, and "zx," which writes shell scripts in JavaScript, has appeared.
I tried using "zx" with high expectations, but I did not find it very useful, as it is like a library that can call shell scripts from JavaScript, and data exchange is still done via standard output.
Personally, I would be happy to see a new version of the shell script, which can be written in the current style.