问题描述
我多次使用 jq
从 AWS CLI 返回的 JSON 中解析、选择值等,例如ec2 describe-instances
等
现在我使用 dockerized version of AWS CLI v2 来获取 CloudWatch 日志组列表:
$ alias aws='docker run --rm -it -v ~/.aws:/root/.aws -e AWS_PROFILE -e AWS_REGION amazon/aws-cli'
$ aws logs describe-log-groups
{
"logGroups": [
{
...
}
]
}
这看起来像是正确的 JSON;但是,当将此管道传送到 jq
时,我得到:
parse error: Invalid numeric literal at line 1,column 2
如果在二进制编辑器中查看从 aws
返回的 JSON,或者使用 jq
:s inputs
特性,我看到它包含很多控制代码:
[
"\u001b[?1h\u001b=\r{\u001b[m\r"," \"logGroups\": [\u001b[m\r"," {\u001b[m\r"," \"logGroupName\": \"/aws/lambda/...
...
在我看来,是因为我通过 docker 使用 AWS CLI 导致了这种情况,因为当使用使用 pip
安装的老式 AWS CLI v1 时,它不会发生 - 但也可能是v2 与 v1 是关键区别,而不是使用 docker 作为我猜的环境(我从未尝试过本地安装 v2)。
这些控制代码,例如\u001b[m
,看起来像 ANSI 代码来控制格式,如粗体、颜色等。但 AFAIK AWS CLI 不使用彩色/ANSI 输出。为什么它们包含在返回的 JSON 中?是否有一个简单的工具可以将它们剥离,以便我可以继续使用 dockerized AWS CLI v2 并将输出通过管道传输到 jq
?我使用复杂的 sed
模式找到了其他答案,我想一定有更简单的方法来做到这一点吗?
编辑:这是一个显示使用 xxd
的控制代码的最小示例。我故意列出带有不匹配过滤器的日志组以获得空数组:
$ aws logs describe-log-groups --log-group-name-prefix FOO > foo.txt
$ xxd foo.txt
00000000: 1b5b 3f31 681b 3d0d 7b1b 5b6d 0d0a 2020 .[?1h.=.{.[m..
00000010: 2020 226c 6f67 4772 6f75 7073 223a 205b "logGroups": [
00000020: 5d1b 5b6d 0d0a 7d1b 5b6d 0d0a 0d1b 5b4b ].[m..}.[m....[K
00000030: 1b5b 3f31 6c1b 3e .[?1l.>
$ cat foo.txt | jq
parse error: Invalid numeric literal at line 1,column 2
$
在使用非 dockerized AWS CLI v1 时显示与 xxd
相同的内容:
00000000: 7b0a 2020 2020 226c 6f67 4772 6f75 7073 {. "logGroups
00000010: 223a 205b 5d0a 7d0a ": [].}.
解决方法
aws
CLI 将其输出提供给 less
,因为 a) 您已经分配了一个带有 -it
标志的伪 tty,b) 就进程而言,它直接输出到 tty 而不是管道,并且 c) 你没有 told it do anything else instead。正确的解决方法是删除 -it
- it's only there for when you need to provide interactive input,如果您将输出通过管道传输到 jq,那么您不需要或不需要交互式输入。但是,如果您尝试设置别名或函数以无缝地代替 aws
,您需要根据是否需要交互式输入来决定是否传递 -it
。你可以试试这个:
function daws() {
local usetty
if [ -t 1 ]
then
usetty=-it
else
usetty=
fi
docker run --rm $usetty -v ~/.aws:/root/.aws -e AWS_PROFILE -e AWS_REGION amazon/aws-cli "$@"
}
在一行中:
function daws() { local usetty; if [ -t 1 ]; then usetty=-it; else usetty=; fi; docker run --rm $usetty -v ~/.aws:/root/.aws -e AWS_PROFILE -e AWS_REGION amazon/aws-cli "$@"; }
或者,您可以传递 --no-cli-pager
或将环境变量 AWS_PAGER
设置为 cat
,但我都尝试了,虽然它们没有导致任何错误,但仍然有一些奇怪的混乱换行符未对部分输出应用回车符的输出。