[英]Is there a way to use `script` with shell functions? (colorized output)
I'm using a script to run several tests (npm, python etc...) 我正在使用脚本运行多个测试(npm,python等...)
These have colored outputs. 这些都有彩色输出。
I'm actually running some of these tests in parallel sending processes in the background, and capturing output in a variable to display when done (as opposed to letting the output come to TTY and having multiple outputs mixed up together). 我实际上在后台并行发送进程中运行其中一些测试,并在变量中捕获输出以在完成时显示(而不是让输出到达TTY并将多个输出混合在一起)。
All works well, but the output is not colored, and I would like to keep the colors. 一切都很好,但输出没有颜色,我想保持颜色。 I understand it is because it is not an output to a TTY so color is stripped, and I looked for tricks to avoid this.
我明白这是因为它不是TTY的输出,所以颜色被剥离,我寻找诀窍来避免这种情况。
This answer: Can colorized output be captured via shell redirect? 这个答案: 可以通过shell重定向捕获彩色输出吗?
offers a way to do this, but doesn't work with shell functions 提供了一种方法,但不适用于shell函数
If I do: 如果我做:
OUTPUT=$(script -q /dev/null npm test | cat)
echo -e $OUTPUT
I get the output in the variable and the echo
command output is colored. 我得到变量中的输出,并且
echo
命令输出是彩色的。
but if f I do: 但如果我这样做:
function run_test() { npm test; }
OUTPUT=$(script -q /dev/null run_test | cat)
echo -e $OUTPUT
I get: 我明白了:
script: run_test: No such file or directory
If I call the run_test
function passing it to script like: 如果我调用
run_test
函数将其传递给脚本,如:
function run_test() { npm test; }
OUTPUT=$(script -q /dev/null `run_test` | cat)
echo -e $OUTPUT
it's like passing the output that is already eval'd without the colors, so the script output is not colored. 这就像传递已经没有颜色的eval'd的输出,因此脚本输出没有着色。
Is there a way to make shell functions work with script
? 有没有办法使shell函数与
script
?
I could have the script call in the function like: 我可以在函数中调用脚本:
function run_test() { script -q /dev/null npm run test | cat; }
but there are several issues with that: 但是有几个问题:
PS: I also tried npm config set color always
to force npm to always output colors, but that doesn't seem to help, plus I have other functions to call that are not all npm, so it would not work for everything anyways. PS:我也试过
npm config set color always
迫使npm总是输出颜色,但这似乎没有帮助,加上我有其他函数来调用并非所有npm,所以它不适用于所有事情。
You can use a program such as unbuffer
that simulates a TTY to get color output from software whose output is actually eventually going to a pipeline. 您可以使用模拟TTY的
unbuffer
等程序从输出实际最终进入管道的软件中获取颜色输出。
In the case of: 如果是:
unbuffer npm test | cat
...there's a TTY simulated by unbuffer
, so it doesn't see the FIFO going to cat
on its output. ...有一个由
unbuffer
模拟的TTY,因此它没有看到FIFO在其输出上变为cat
。
If you want to run a shell function behind a shim of this type, be sure to export it to the environment, as with export -f
. 如果要在此类型的垫片后面运行shell函数,请确保将其导出到环境中,就像
export -f
。
Demonstrating how to use this with a shell function: 演示如何在shell函数中使用它:
myfunc() { echo "In function"; (( $# )) && { echo "Arguments:"; printf ' - %s\n' "$@"; }; }
export -f myfunc
unbuffer bash -c '"$@"' _ myfunc "Argument one" "Argument two"
I tried unbuffer
and it doesn't seem to work with shell functions either 我尝试了
unbuffer
,它似乎也不适用于shell函数
script doesn't work by passing it a shell function, however it's possible to pass some STDIN type input, so what ended up working for me was 脚本通过传递shell函数不起作用,但是可以传递一些STDIN类型的输入,所以最终为我工作的是
script -q /dev/null <<< "run_test"
or 要么
echo "run_test" | script -q /dev/null
so I could output this to a shell variable, even using a variable as the COMMAND like: 所以我可以将它输出到shell变量,甚至使用变量作为COMMAND,如:
OUTPUT=$(echo "$COMMAND" | script -q /dev/null)
and later output the colored output with 然后输出彩色输出
echo -e $OUTPUT
Unfortunately, this still outputs some extra garbage (ie the shell name, the command name and the exit
command at the end. 不幸的是,这仍然会输出一些额外的垃圾(即shell名称,命令名称和最后的
exit
命令)。
Since I wanted to capture the output code, I could not pipe the output somewhere else, so I went this way: 由于我想捕获输出代码,我无法在其他地方输出输出,所以我这样做:
run() {
run_in_background "$@" &
}
run_in_background() {
COMMAND="$@" # whatever is passed to the function
CODE=0
OUTPUT=$(echo "$COMMAND" | script -q /dev/null) || CODE=$(( CODE + $? ));
echo -e $OUTPUT | grep -v "bash" | grep -v "$COMMAND";
if [ "$CODE" != "0" ]; then exit 1; fi
}
and use like: 并使用如下:
# test suites shell functions
run_test1() { npm test; }
run_test2() { python manage.py test; }
# queue tests to run in background jobs
run run_test1
run run_test2
# wait for all to finish
wait
I'm skipping the part where I catch the errors and propagate failure to the top PID, but you get the gist. 我正在跳过我捕获错误并将失败传播到顶级PID的部分,但是你得到了要点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.