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

时间:2013-10-22 12:53:57

标签: bash function paradigms

在我尝试的一堆语言中,函数可以返回大量类型的值(整数,字符串,各种对象,返回函数的函数等),但在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的帮助下,这是工作代码(减去愚蠢的双斜线问题):

#!/usr/bin/env bash
function firefoxcache {
cache_dir=$1
videos_dir=$2
echo "$cache_dir", "$videos_dir"
echo
for video in $(findallvideos $cache_dir); do
echo cp $video $videos_dir/$(basename $video).flv
cp $video $videos_dir/$(basename $video).flv
done;
}

function findallvideos {
#echo findallvideos "$1"
for video in $(find $1 -exec file {} \; | grep -i $VIDEOS_REGX | cut -f1 -d:); do
echo $video;
done;
}

firefoxcache $1 $2

# cp /home/chaouche/.cache/mozilla/firefox/qmkhe4mr.default/Cache/4/B6/6AB61d01 VIDEOS//6AB61d01.flv
# cp /home/chaouche/.cache/mozilla/firefox/qmkhe4mr.default/Cache/4/28/A3524d01 VIDEOS//A3524d01.flv
# cp /home/chaouche/.cache/mozilla/firefox/qmkhe4mr.default/Cache/4/D2/29D4Ad01 VIDEOS//29D4Ad01.flv
# cp /home/chaouche/.cache/mozilla/firefox/qmkhe4mr.default/Cache/4/A1/15D75d01 VIDEOS//15D75d01.flv
# cp /home/chaouche/.cache/mozilla/firefox/qmkhe4mr.default/Cache/4/A3/2C971d01 VIDEOS//2C971d01.flv
# cp /home/chaouche/.cache/mozilla/firefox/qmkhe4mr.default/Cache/4/7E/E17D8d01 VIDEOS//E17D8d01.flv
# cp /home/chaouche/.cache/mozilla/firefox/qmkhe4mr.default/Cache/4/AC/5295Dd01 VIDEOS//5295Dd01.flv

3 个答案:

答案 0 :(得分:3)

Bash(和其他shell)正在使用流来传递值。您引用的返回值与异常相关,而不是返回值。如果返回值为≠0,则其语义通常是发生错误,并且调用方不应该继续,就好像什么也没发生一样。

另一方面,如果你想返回一个值,那么被调用的函数,脚本,子进程, print 的值应该返回{ {1}}。然后调用者可以捕获该输出并使用它:

stdout

square() { echo $[ $1 * $1 ] } a=4 b=$(square $a) echo "$a squared is $b" 是执行该操作的主流;但是,您可以使用其他流,例如stdout;所以shell可以“返回”多个值。

当然,还有其他方面,例如子进程不一定必须终止父亲阅读并根据其输出进行操作。但我认为这对你的问题有点不合适。

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

在你的情况下,我会使用xargs然后使用循环:

read

答案 1 :(得分:2)

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

e.g。

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.

答案 2 :(得分:1)

  

So for example, suppose you want to write a function that want to return something to another function. How should you do it ?

通过在函数的stdout上写一些东西,让调用函数捕获输出。

示例:

function foo () {
    echo "hello"
}

function fooCaller() {
    ret=$(foo)
    [[ "$ret" == "hello" ]] && echo "hello returned from function foo()"
}