我在 shell 脚本 post.sh 中有一个有效的 POST 请求:
curl -s --location --request POST \
--header 'Content-Type: application/json'. \
--data '{"password": "'$(echo $PW)'"}'. \
https://api-sec.path/managed-vault/login/myuser
它返回包含以下内容的 json:"auth":{"client_token":"my.token"}
post.sh | jq .auth.client_token
返回“my.token”
我想将其传递给另一个独立工作的 GET 请求 (get.sh):
TOKEN=$(cat)
curl --location --request GET \
--header 'X-Vault-Token: '$(echo $TOKEN)''
https://api-sec.path/managed-secrets/myuser
手动粘贴TOKEN的工作原理:get.sh sQ34my./toKeN//z
这将返回一个错误,表明我的令牌错误:
post.sh | jq .auth.client_token | get.sh
如何修复这个管道卷曲输出?
答案1
看来您想使用两个单独的 shell 脚本,post.sh
并且get.sh
.
#!/bin/sh
# This is post.sh
curl -s --location --request POST \
--header 'Content-Type: application/json' \
--data "$( jo password="$PW" )" \
'https://api-sec.path/managed-vault/login/myuser'
我在此处使用jo
它来创建 JSON 有效负载,确保密码已正确编码。要使用jq
它,只需将jo
命令替换为
jq --arg password "$PW" -n '{ password: $password }'
不要将 shell 变量PW
直接注入到 JSON 文档中,因为这样做会产生代码注入漏洞,并且还需要您单独对密码字符串进行编码。
#!/bin/sh
# This is get.sh
token=$( ./post.sh | jq -r '.auth.client_token' )
curl --location --request GET \
--header "X-Vault-Token: $token" \
'https://api-sec.path/managed-secrets/myuser'
该get.sh
脚本只是调用post.sh
(假设位于当前目录中),从响应中解析出令牌并将其分配给token
shell 变量。
get.sh
如果您愿意,您仍然可以从标准输入读取令牌。以下假设令牌在单行上传递:
#!/bin/sh
# This is get.sh
if [ -t 0 ]; then
printf 'Enter token: ' >&2
fi
IFS= read -r token
curl --location --request GET \
--header "X-Vault-Token: $token" \
'https://api-sec.path/managed-secrets/myuser'
如果该脚本的标准输入直接连接到终端,则该脚本将提示您输入令牌。如果没有,您将不会收到任何提示。
您可以将此变体称为get.sh
as
./post.sh | jq -r '.auth.client_token' | ./get.sh
您的代码存在一些问题:
在您的第一个脚本中,
$PW
不带引号使用。这意味着密码将被分成空格、制表符和换行符上的多个单词。然后每个单词都会经历文件名通配。如果您使用带有空格和文件名通配符(例如 、 和 )的密码,这将会*
出现[
问题?
。关于TOKEN
变量,您在第二个脚本中也遇到了同样的问题。使用
$(echo $variable)
in 代替 just$variable
是一种反模式,有几个问题(不带引号的变量扩展以及echo
如果字符串包含反斜杠转义符则可能会修改字符串的内容)。如前所述,如果密码包含双引号或文本制表符等字符,则构建 JSON 文档的方式可能很容易破坏文档的格式。您将需要正确引用密码,我已经展示了两种方法上面(使用方便的
jo
工具和jq
您已经使用的实用程序)。jq
默认情况下,将输出 JSON 编码的字符串。当您调用jq
获取令牌时,您将获得一个 JSON 字符串,其中包含一组双引号。jq
与其-r
( ) 选项一起使用--raw-output
将确保您获得令牌作为解码后的字符串。