У меня была эта проблема, и, прежде чем переходить к чему-либо еще, вы можете перезагрузить компьютер.
Документ JSON, который вы получаете от своей команды, похоже, содержит другой закодированный документ JSON. Именно из этого закодированного документа вы, кажется, хотите получить данные.
Чтобы получить доступ к внутреннему документу, мы можем использоватьjq
:
aws... |
jq -r '.Policy'
Чтобы получить значение ключа Effect
из бита, содержащего этот ключ aws:SecureTransport
, нам нужно снова проанализировать документ:
aws... |
jq -r '.Policy' |
jq -r '.Statement[] | select(.Condition.Bool."aws:SecureTransport").Effect'
Последний вызов jq
проходит по всем элементам массива Statement
в поисках того, у которого есть ключ с именем .Condition.Bool."aws:SecureTransport"
. Затем он получает значение ключа Effect
, связанного с этим элементом Statement
.
Выполнение этого для ваших данных выводит значение Deny
.
Если вы хотите значение этого ключа .Condition.Bool."aws:SecureTransport"
(false
в вашем документе ), используйте .Condition.Bool."aws:SecureTransport"
вместо .Effect
выше.
В качестве альтернативы используйте инструкцию fromjson
в jq
вместо второго вызова jq
:
aws... |
jq -r '.Policy | fromjson |.Statement[] | select(.Condition.Bool."aws:SecureTransport").Effect'
Здесь fromjson
декодирует закодированный документ JSON и передает его на более поздние этапы обработки.
Просто для справки: внутренний закодированный документ JSON выглядит следующим образом(aws... | jq -r '.Policy | fromjson'
):
{
"Version": "2012-10-17",
"Id": "S3SecureTransportPolicy",
"Statement": [
{
"Sid": "ForceSSLOnlyAccess",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::amn/*",
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
},
{
"Sid": "AWSCloudTrailAclCheck20150319",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::amn"
},
{
"Sid": "AWSCloudTrailWrite20150319",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::amn/AWSLogs/405042254276/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
Во-первых, не делайте этого! Используйте jq
, как описано в ответе Кусалананды . Это гораздо более надежное решение, чем возиться с регулярными выражениями. Тем не менее, вот один из способов сделать это сgrep
:
aws... | grep -oP 'aws:SecureTransport.":."\K.+?(?=\\")'
То будет искать aws:SecureTransport
, то любой символ(.
; это просто проще, чем написать \\
, чтобы избежать косой черты ), а затем "
. \K
отбрасывает все, что совпало до этой точки (, поэтому часть, совпадающая с aws:SecureTransport.":."
). Затем найдите самую короткую строку (.+?
), за которой следует \"
((?=\\")
).
Выполнение этого в файле, содержащем вывод вашего примера, дает:
$ grep -oP 'aws:SecureTransport.":."\K.+?(?=\\")' file
false