包含 AWK 的 CURL 脚本通过 SSH 故障打印 Docker Image Digest
Posted
技术标签:
【中文标题】包含 AWK 的 CURL 脚本通过 SSH 故障打印 Docker Image Digest【英文标题】:CURL script containing AWK fails over SSH to print Docker Image Digest 【发布时间】:2022-01-14 13:21:00 【问题描述】:以下curl
脚本失败超过ssh
,
#!/bin/bash
reg='dockreg:5000'
image='mubu6'
itag='v6'
auth='-u user:pass'
accept=(
-H "Accept: application/vnd.docker.distribution.manifest.v2+json"
)
ssh -tt root@192.168.122.60 "
echo get digest; read
curl $auth -vsk \
-X DELETE \
"https://$reg/v2/$image/manifests/$(
curl $auth \
-vk "$accept[@]" \
https://$reg/v2/$image/manifests/$itag 2>&1 |\
grep docker-content-digest | awk 'print $3' |\
tr -d $'\r'
)"
"
不打印digest
在下面第一行的manifests
之后,而在最后一行抛出404 error
。
DELETE /v2/mubu6/manifests/ HTTP/2
> Host: dockreg:5000
> authorization: Basic YWxleGFuZGVyOnNvZmlhbm9z
> user-agent: curl/7.68.0
> accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 404
它在节点上成功运行,
echo get digest; read
curl $auth -vsk \
-X DELETE \
"https://$reg/v2/$image/manifests/$(
curl $auth \
-vk "$accept[@]" \
https://$reg/v2/$image/manifests/$itag 2>&1 |\
grep docker-content-digest | awk 'print $3' |\
tr -d $'\r'
)"
打印第一行manifests
之后的digest
,最后一行HTTP/2 202 exit code
:
DELETE /v2/mubu6/manifests/sha256:0aa2280cc066ef4f8279122fc9f76d15e96a8bfa642a54dadbf8c9985f3de747 HTTP/2
> Host: dockreg:5000
> authorization: Basic YWxleGFuZGVyOnNvZmlhbm9z
> user-agent: curl/7.68.0
> accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 202
失败可能与awk
有关,因为它已经需要tr -d $'\r'
才能将line feed
正确传递给curl
。
此外,我已经知道awk
不能开箱即用 ssh
只能成功运行以下,转义后 $2
in awk
:
for x in $NODE_IPS[@]; do
ssh -tt root@$x "
dpkg -l | grep '^rc' | awk 'print \$2' | \
xargs -p dpkg --purge
echo -e "continue to next node \c"; read
"
不幸的是,我的curl
尝试相同的解决方案而不是ssh
脚本抛出错误:
awk: cmd. line:1: print \$3
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: print \$3
awk: cmd. line:1: ^ syntax error
我还在整个脚本中尝试了很多不同的引用排列,但均无济于事。 我对这一切都很陌生,任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:您有三组相互嵌套的双引号。它们对 bash 解析造成了严重破坏。如果您希望将引号内的引号传输到 SSH 隧道的远端,您需要使用反斜杠对其进行转义...
ssh 可能只看到第一组引号内的内容:
ssh -tt root@192.168.122.60 "
echo get digest; read
curl $auth -vsk \
-X DELETE \
"
Bash 有两种引号:单引号和双引号。
单引号将导致 bash 不解释字符串中的任何转义、变量等。
双引号将导致 bash 完全替换转义和变量。
您可以将单引号放在双引号内,变量仍将被替换:
DEMOVAR="just testing"
echo "This is a 'test of $DEMOVAR' to show single quotes have no effect here"
# RESULT:
This is a 'test of just testing' to show single quotes did not affect substitution
但是在单引号里面放双引号的时候就不一样了:
echo 'This is a "test of $DEMOVAR" to show that single quotes prevent substitution'
# RESULT:
This is a "test of $DEMOVAR" to show that single quotes prevent substitution
为了更复杂,你可以在双引号内“转义”双引号,但不能在单引号内转义单引号:
echo "This set of \"Double quotes\" will show"
但是单引号会连接起来:
echo 'Single quotes \'will not escape\' inside single quotes'
上面的行将打开一个单引号,然后在第一个反斜杠引号之后将其关闭。以下文本:不会在单引号内转义 不在任何引号内,因此第二个反斜杠引号被 bash 转义。最后,行尾的引号打开一个新的 QUOTE 块,因此按 Enter 将等待另一个引号以关闭该块。
困惑???我花了好几年才理解这种细微差别
为了使您的代码更加困难,您将其包装在一个 SSH 中,该 SSH 将内容从第一个双引号传输到第二个双引号,但其余的行并不是真的在双引号内。问题是 bash 替换在哪里完成?您正在尝试使用 $(curl xxxxx) 来获取摘要,但我无法确定您是希望在本地机器上还是在远程机器上。
我建议您将命令分解为多个 SSH 命令以摆脱嵌套:
#!/bin/bash
reg='dockreg:5000'
image='mubu6'
itag='v6'
auth='-u user:pass'
# Note I put double quotes inside single quotes
accept='-H "Accept: application/vnd.docker.distribution.manifest.v2+json"'
# NOT sure what this is:
echo get digest; read
# Get the DIGEST. Note that I got rid of the 'grep'
# as awk can also filter, and I moved the 'tr' before the 'awk'
# I am only doing the 'curl' on the remote machine, and
# the entire output is transmitted back. The filters ('tr' and 'awk' )
# are done locally and the DIGEST variable is set locally.
DIGEST=$(ssh root@192.168.122.60 \
"curl $auth -vk $accept https://$reg/v2/$image/manifests/$itag 2>&1" |\
tr -d '\r' |awk '/docker-content-digest/ print $3');
# Now call the DELETE with the preset DIGEST.
ssh root@192.168.122.60 \
"curl $auth -vsk -X DELETE https://$reg/v2/$image/manifests/$DIGEST"
【讨论】:
感谢 DavidG 的提示,我按照你的建议做了,但还是不行。 我用很多细节扩展了答案。嵌套引号和替换时,如果可以避免,最好的建议是不要。使其更易于理解和维护。 是的,这行得通!非常感谢 DavidG 的所有详细解释!以上是关于包含 AWK 的 CURL 脚本通过 SSH 故障打印 Docker Image Digest的主要内容,如果未能解决你的问题,请参考以下文章