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