包含 AWK 的 CURL 脚本无法通过 SSH 打印 Docker Image Digest
CURL script containing AWK fails over SSH to print Docker Image Digest
以下 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 }' |\
tr -d $'\r'
)"
"
不打印 在下面第一个输出行 manifests
之后的 digest
,同时在最后一个输出行上抛出 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 }' |\
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
仅从 运行 成功以下 在 awk
中转义 </code> 后:</p>
<pre><code>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
"
不幸的是,在 ssh
脚本 上尝试 与 我的 curl
相同的解决方案 抛出错误 :
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
我还在整个脚本中尝试了很多不同的引用排列,但都无济于事。
我对这一切都很陌生,非常感谢任何帮助。
你有三组相互嵌套的双引号。他们正在对 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
为了让它更复杂,你可以 'escape' 双引号里面的双引号,但是你不能在单引号里面转义单引号:
echo "This set of \"Double quotes\" will show"
但是单引号会连接起来:
echo 'Single quotes \'will not escape\' inside single quotes'
以上行将打开一个单引号,然后在第一个反斜杠引号后立即将其关闭。以下文本: will not escape' inside single quotes is not inside any quotes 因此第二个反斜杠引号被 [=49= 转义].最后,行尾的报价 OPENS 一个新的 QUOTE 块 因此按回车键将等待另一个报价关闭该块。
困惑???我花了很多年才理解这种细微差别
为了使您的代码更加困难,您将其包装在 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 }');
# 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}"
以下 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 }' |\
tr -d $'\r'
)"
"
不打印 在下面第一个输出行 manifests
之后的 digest
,同时在最后一个输出行上抛出 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 }' |\
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
仅从 运行 成功以下 在 awk
中转义 </code> 后:</p>
<pre><code>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
"
不幸的是,在 ssh
脚本 上尝试 与 我的 curl
相同的解决方案 抛出错误 :
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
我还在整个脚本中尝试了很多不同的引用排列,但都无济于事。 我对这一切都很陌生,非常感谢任何帮助。
你有三组相互嵌套的双引号。他们正在对 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
为了让它更复杂,你可以 'escape' 双引号里面的双引号,但是你不能在单引号里面转义单引号:
echo "This set of \"Double quotes\" will show"
但是单引号会连接起来:
echo 'Single quotes \'will not escape\' inside single quotes'
以上行将打开一个单引号,然后在第一个反斜杠引号后立即将其关闭。以下文本: will not escape' inside single quotes is not inside any quotes 因此第二个反斜杠引号被 [=49= 转义].最后,行尾的报价 OPENS 一个新的 QUOTE 块 因此按回车键将等待另一个报价关闭该块。
困惑???我花了很多年才理解这种细微差别
为了使您的代码更加困难,您将其包装在 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 }');
# 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}"