我正在编写一个shell脚本,用于重定向程序的[1,2,3] [1,2,5] [1,4,2] [2,3,1] [2,2,1]
[3,7,1] [] [1,1,1] [] [1,2,2]
[] [] [] [] []
和STDOUT
输出。重定向的目标是变量。通常,目标是一个文件,在这种情况下,以下工作正常。
STDERR
但是,有时我不想重定向到文件,但想要像平常一样打印到simple_redirect()
{
myfunc=$1
myfile=$2
myfunc &>myfile
}
simple_redirect ls text.txt
。
如果STDOUT
myfile
为&1
,则会收到以下错误消息:
STDOUT
如果我运行命令
$myfile: ambiguous redirect
,我看到:ls &>&1
。
通过分别重定向parse error near '&'
和STDOUT
:STDERR
,我想到了一种解决方法。但是,我更喜欢这个选项,因为我必须重用变量并且它的可读性较差。有更简单的方法吗?
答案 0 :(得分:1)
如果您使用的是bash 4.1或更新版本,则以下内容将起作用:
redirect_to() {
local myfile=$1; shift
case $myfile in
-) "$@" ;;
"&"*) "$@" >&${myfile#"&"} 2>&1 ;;
*) "$@" >"$myfile" 2>&1 ;;
esac
done
redirect_to - ls -l foo.d/ # no redirection
redirect_to &2 ls -l foo.d/ # redirection to FD 2
redirect_to foo.list ls -l foo.d/ # redirection to foo.list
redirect_to /dev/stdout ls -l foo.d/ # consider doing this anyhow
>&$foo
是一个bash 4.1扩展,它允许使用变量来提供文件描述符编号 - 在此之前,您需要使用>/dev/fd/${foo#"&"}
代替(如果您的操作系统提供)他们;在问题上给出linux标签,这应该是一个普遍安全的假设。)
如果您没有bash 4.1或更新版本(特别是如果您的目标是POSIX sh而不是bash),则无法在>&$foo
之后实施eval
选项 - a使用/dev/stdout
,/dev/stderr
,/dev/fd/1
等的has substantial security caveats最好的原语。
使用旧版本的bash安全地执行此操作可能看起来像这样,使用printf %q
来清理文字参数和%d
以确保文件描述符只能是数字:
"&"*) printf -v cmd_str '%q ' "$@"
printf -v redir_suffix '>&%d' "${myfile#"&"}"
eval "$cmd_str $redir_suffix 2>&1" ;;