我的目标是将应用程序 ( ) 的所有输出 (stdout
和)复制、重定向到一个文件,同时保留应用程序 ( )和的通常行为。stderr
apt-get
apt-get
stdout
stderr
如何创建文件描述符stdout
和的真实副本stderr
?我希望保持stdout
和stderr
尽可能“自然”。例如,如果它正在运行apt-get
,我希望保留颜色和进度信息。[1]
这是一个例子。 (包装器做了更多的事情,只是保持简单。)
#!/bin/bash
temp_dir="$(mktemp --directory)"
logfile="$temp_dir/log"
unbuffer apt-get "$@" 1> >(tee -a "$logfile") 2> >(tee -a "$logfile" >&2)
unbuffer
是否可以在没有//script
仅tee
使用bash
内置函数的情况下实现这一目标?
(为了使包装器更简单并减少对外部二进制文件的依赖。否则这可能会导致与强制访问控制等发生冲突。)
(使用脚本(1)其手册页不鼓励在非交互式脚本中使用。)
[1]
22% [8 Packages 3,449 kB/7,098 kB 49%]
174 kB/s 4min 57s
答案1
这POSIXshell faketee
函数没有依赖项:
faketee() {
if [ "$1" = '-a' ] ; then
shift
while read -r x ; do
echo "$x" >> "$1"
echo "$x"
done
else
while read -r x ; do
echo "$x" > "$1"
echo "$x"
done
fi
}
bash
在一个存在的文件上测试它ls
(输出一行到标准输出),以及一个不存在的文件名(输出另一行到标准错误错误率):
cd /tmp
ls /bin/bash /bin/nosuchfile 1> >(faketee -a std.log) \
2> >(faketee -a err.log >&2)
输出:
/bin/bash
ls: cannot access '/bin/nosuchfile': No such file or directory
...然后使用另外两个这样的文件名再次运行它:
ls /bin/dash /bin/nohowsuchfile 1> >(faketee -a std.log) \
2> >(faketee -a err.log >&2)
输出:
/bin/dash
ls: cannot access '/bin/nohowsuchfile': No such file or directory
现在检查日志文件以查看是否-a
待定开关工作原理:
grep -n '.' std.log err.log
输出表明附加的重定向位于应有的位置:
std.log:1:/bin/bash
std.log:2:/bin/dash
err.log:1:ls: cannot access '/bin/nosuchfile': No such file or directory
err.log:2:ls: cannot access '/bin/nohowsuchfile': No such file or directory