Bash (and other shells) are using streams to communicate values. The return value you refer to is rather related to exceptions than to return values. If a return value is ≠ 0 the semantics of this is typically that an error has occurred and the caller should not continue as if nothing has happened.
If, on the other hand, you want to return a value, the called function, script, subprocess, whatever should print the value-to-return to stdout
. The caller can then capture that output and use it:
square() {
echo $[ $1 * $1 ]
}
a=4
b=$(square $a)
echo "$a squared is $b"
stdout
is the main stream to perform that; you can, however use other streams like stderr
as well; so shells can "return" more than one value.
There are other aspects, of course, like subprocesses do not necessarily have to terminate for the father to read and act upon their output. But I think that's a little out of scope for your question.
Concerning your concrete usecase you have to find a solution for the age-old problem of how to transmit lists of values via a byte stream. One solution is to use the print0
option of the find
Unix tool. It prints the file names with a terminating zero byte for each (which is one of the few characters which cannot occur in a Unix path). The reader process then has to expect this format of course. You can use use the option -0
in xargs
for instance.
In your case, I would use a loop using read
then:
function findallfiles {
find "$1" -print0
}
function findallvideos {
findallfiles | while IFS='' read -d $'\0' f
do
[[ "$(file -b "$f")" =~ "$VIDEOS_REGX" ]] && printf "%s\0" "$f"
done
}
function firefoxcache {
cache_dir=$1
videos_dir=$2
findallvideos "$videos_dir" | while IFS='' read -d $'\0' video
do
echo cp "$video" "$videos_dir/$(basename "$video").flv"
done
}