Bash

如何將作為字元串的變數嵌套在另一個變數中,該變數是命令的已保存輸出?

  • August 3, 2021

如何將作為字元串的變數嵌套在另一個變數中,該變數是命令的已保存輸出?

我想完成這段程式碼的作用:

xmrprice=$(curl -s 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin%2Cbitcoin-cash%2Clitecoin%2Cmonero&vs_currencies=usd&include_market_cap=true' |jq -r '.monero'|jq -r '.usd')
echo "The price of Monero is $xmrprice"
btcprice=$(curl -s 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin%2Cbitcoin-cash%2Clitecoin%2Cmonero&vs_currencies=usd&include_market_cap=true' |jq -r '.bitcoin'|jq -r '.usd')
echo "The price of BTC is $btcprice"
ltcprice=$(curl -s 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin%2Cbitcoin-cash%2Clitecoin%2Cmonero&vs_currencies=usd&include_market_cap=true' |jq -r '.litecoin'|jq -r '.usd')
echo "The price of Litecoin is $ltcprice"

但沒有呼叫curl三遍。刪除-s標誌將證明 curl 確實被呼叫了 3 次。我想從輸出中分配字元串

curl -s https://api.coingecko.com/api/v3/simple/price?ids=bitcoin%2Cbitcoin-cash%2Clitecoin%2Cmonero&vs_currencies=usd&include_market_cap=true

到一個變數,然後從中提取xmrpricebrcprice和的值ltcprice。就像這個 Python 程式碼一樣:

#!/usr/bin/python3

#pip3 install requests

import requests
import json

result = requests.get("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin%2Cbitcoin-cash%2Clitecoin%2Cmonero&vs_currencies=usd&include_market_cap=true", headers = {"accept":"application/json"})

print("Monero's and Bitcoin's prices as of now:")
print(str(result.json()["monero"]["usd"]))
print(str(result.json()["bitcoin"]["usd"]))

我在 Bash中的嵌套變數上遇到過這個問題,但它更多地涉及將多個命令的嵌套輸出分配給一個變數。

我已經嘗試了所有這些:

response=$(curl -s https://api.coingecko.com/api/v3/simple/price?ids=bitcoin%2Cbitcoin-cash%2Clitecoin%2Cmonero&vs_currencies=usd&include_market_cap=true)
#xmrprice=(${response}|jq -r '.monero'|jq -r '.usd') #syntax error near unexpected token `|'
#xmrprice=("${response}"|jq -r '.monero'|jq -r '.usd') #syntax error near unexpected token `|'
#xmrprice=$("${response}"|jq -r '.monero'|jq -r '.usd') #{"error":"Missing parameter vs_currencies"}: command not found
#xmrprice=$("{response}"|jq -r '.monero'|jq -r '.usd') #: {response}: command not found

echo "The price of Monero is ${xmrprice}". 

它都不起作用。評論描述了我從 Bash 中得到的錯誤。

你接近你正在尋找的東西。你只缺少一個echo.

#!/usr/bin/env bash
response=$(curl -s 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin%2Cbitcoin-cash%2Clitecoin%2Cmonero&vs_currencies=usd&include_market_cap=true')
xmrprice=$(echo "${response}"|jq -r '.monero'|jq -r '.usd')
echo "${xmrprice}"

編輯:正如 Kusalananda 所指出的,您還缺少 curl 命令中 URL 周圍的引號。

我可能會這樣做:

#!/bin/sh

unset -v xmrprice btcprice ltcprice

url='https://api.coingecko.com/endpoint/path'

eval "$(
   curl -s "$url" |
   jq -r '
       @sh "xmrprice=\(.monero.usd|tonumber)",
       @sh "btcprice=\(.bitcoin.usd|tonumber)",
       @sh "ltcprice=\(.litecoin.usd|tonumber)"'
)"

printf '%s is %s\n' \
   'xmrprice' "$xmrprice" \
   'btcprice' "$btcprice" \
   'ltcprice' "$ltcprice"

這呼叫curl 一次並通過單個 jq呼叫傳遞結果文件,而無需將其儲存在文件或變數中。該jq表達式創建三個字元串。每個字元串都是一個變數賦值。@sh運算符 injq確保為 shell 正確引用了字元串。

評估eval變數分配,創建三個 shell 變數。

請注意,程式碼中使用的引號,無論是單引號還是雙引號,都不是偶然的或不需要的(除了參數中的純字元串周圍的單引號之外printf,它們只是為了好看​​)。


如果您實際上對創建 shell 變數不感興趣,則無需這樣做,因為它jq可以用來進行格式化輸出:

#!/bin/sh

url='https://api.coingecko.com/endpoint/path'

curl -s "$url" |
jq -r '
   "xmrprice is at \(.monero.usd|tonumber) USD",
   "btcprice is at \(.bitcoin.usd|tonumber) USD",
   "ltcprice is at \(.litecoin.usd|tonumber) USD"'

引用自:https://unix.stackexchange.com/questions/663132