bash语言中使用的编程范例是什么?

bash语言中使用的编程范例是什么?,bash,function,paradigms,Bash,Function,Paradigms,在我尝试过的一系列语言中,函数可以返回大量类型的值(int、string、各种对象、返回函数的函数等),但在bash中,似乎唯一允许的类型是int,它不应该被其他函数使用,而是被shell本身使用,以知道一切是否正常(返回0),或者,如果发生错误,则返回的值是错误代码 例如,假设您要编写一个函数,该函数希望将某些内容返回给另一个函数。你应该怎么做 假设您想编写一个findvideos函数,返回在特定文件夹(及其子文件夹)中找到的每个视频。如果你想在另一个函数中使用该函数的结果,你会怎么做?通过回

在我尝试过的一系列语言中,函数可以返回大量类型的值(int、string、各种对象、返回函数的函数等),但在bash中,似乎唯一允许的类型是int,它不应该被其他函数使用,而是被shell本身使用,以知道一切是否正常(返回0),或者,如果发生错误,则返回的值是错误代码

例如,假设您要编写一个函数,该函数希望将某些内容返回给另一个函数。你应该怎么做

假设您想编写一个findvideos函数,返回在特定文件夹(及其子文件夹)中找到的每个视频。如果你想在另一个函数中使用该函数的结果,你会怎么做?通过回声和管道

我在写这样一个小脚本的时候被困在了:

function firefoxcache {
    cache_dir=$1
    videos_dir=$2
    videos=$(findallvideos $videos_dir)
    for video in $videos; do
    echo cp $video $videos_dir/$(basename $video).flv
    done;
}

function findallvideos {
    videos=$(find $1 -exec file {} \; | grep -i $VIDEOS_REGX | cut -f1 -d:)
    #echo $videos
    return videos
}   
编辑

在Stackers的帮助下,以下是工作代码(减去愚蠢的双斜杠问题):

例如,假设您要编写一个函数,该函数希望向另一个函数返回某些内容。您应该怎么做?

通过从函数在标准输出上写入内容,让调用方函数捕获输出

示例:

function foo () {
    echo "hello"
}

function fooCaller() {
    ret=$(foo)
    [[ "$ret" == "hello" ]] && echo "hello returned from function foo()"
}
Bash(和其他shell)使用流来传递值。您引用的返回值与异常相关,而不是与返回值相关。如果返回值为≠ 0此操作的语义通常是发生了错误,调用方不应像什么都没有发生一样继续

另一方面,如果您想要返回一个值,则被调用的函数、脚本、子进程,无论什么都应该打印该值以返回到
stdout
。然后调用方可以捕获该输出并使用它:

square() {
  echo $[ $1 * $1 ]
}

a=4
b=$(square $a)
echo "$a squared is $b"
stdout
是执行该操作的主流;但是,您也可以使用其他流,如
stderr
;因此,Shell可以“返回”多个值

当然,还有其他方面,比如子进程不一定要终止,父进程才能读取并处理它们的输出。但我认为这有点超出了你的问题范围

关于您的具体用例,您必须为如何通过字节流传输值列表这一古老问题找到解决方案。一种解决方案是使用
find
Unix工具的
print0
选项。它打印文件名,每个文件名都有一个终止的零字节(这是Unix路径中不能出现的少数字符之一)。当然,读者过程必须期望这种格式。例如,您可以在
xargs
中使用选项
-0

在您的情况下,我将使用一个循环,使用
read
,然后:

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
}

Shell脚本只能从函数类型返回整数值。如果希望从它们中输出字符串,则必须回显字符串,然后在分配给变量的子shell中捕获该输出

e、 g


真正说明了函数之间不应该使用return。这与传统语言是如此不同。感谢您指出这一点。假设我希望在foo中有调试打印,调用方显然不应该捕获这些打印,我可以怎么做?如果您希望回显调试消息,请使用stderr而不是stdout
echo“test”>&2
-此输出不会像往常一样被sub-shell.Rich和非常有文档记录的答案捕获。谢谢@Alfe。简单的回声和for循环对我有用:
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
}
function foo()
{
    if [ "$1" = "hello" ] ; then
        echo "world";
        return 0;
    fi
    return 1;
}

a=$(foo "hello"); # a = world
echo $?;  # prints 0 - return values and exit status's are always assigned here.

a=$(foo); # a = empty string
echo $?;  # prints 1.