循环Bash中的计时器

循环Bash中的计时器,bash,Bash,我有一个令牌在30分钟后过期,我想续订此令牌,直到30分钟时间过期,我有以下脚本调用api: function token { gen_bearer_token=$(curl -X POST "https://api.foo.bar/oauth2/token" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded"

我有一个令牌在30分钟后过期,我想续订此令牌,直到30分钟时间过期,我有以下脚本调用api:

function token {
        gen_bearer_token=$(curl -X POST "https://api.foo.bar/oauth2/token" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=foo&client_secret=bar" | cut -d '{' -f2 | cut -d '}' -f1)
        bearer_token=$(echo $gen_bearer_token | awk '{print $2}' | cut -d '"' -f2 | cut -d '"' -f1)
        token_type=$(echo $gen_bearer_token | awk '{print $6}' | cut -d '"' -f2 | cut -d '"' -f1)
    }

echo -e "HOSTNAME;LAST_SEEN" > ${file}


ids=$(curl -s -X GET 'https://api.foo.bar/devices/queries/devices-scroll/v1?limit=5000' -H  'accept: application/json' -H  'authorization: '${token_type}' '${bearer_token}'' | jq .resources[])
for id in ${ids}
do
    result=$(curl -s -X GET 'https://api.foo.bar/devices/entities/devices/v1?ids='${id}'' -H  'accept: application/json' -H  'authorization: '${token_type}' '${bearer_token}'' | jq '.resources[] | "\(.hostname) \(.last_seen)"')
    if [[ ! -z ${result} ]]
    then
        hostname=$(echo ${result} | awk '{print $1}' | cut -d '"' -f2)
        last_seen=$(echo ${result} | awk '{print $2}' | cut -d '"' -f1)
        echo -e "${hostname};${last_seen}" >> ${file}
    fi
done
在这个循环中,持续时间超过2小时(可变持续时间)+如果时间超过30分钟,我想创建一个计时器来更新令牌,如果超过30分钟,api中的请求将失败

for id in ${ids}
do
    result=$(curl -s -X GET 'https://api.foo.bar/devices/entities/devices/v1?ids='${id}'' -H  'accept: application/json' -H  'authorization: '${token_type}' '${bearer_token}'' | jq '.resources[] | "\(.hostname) \(.last_seen)"')
    if [[ ! -z ${result} ]]
    then
        hostname=$(echo ${result} | awk '{print $1}' | cut -d '"' -f2)
        last_seen=$(echo ${result} | awk '{print $2}' | cut -d '"' -f1)
        echo -e "${hostname};${last_seen}" >> ${file}
    fi
done

bash
作为合适的内置计时器:
SECONDS
变量

其值是其初始值加上自最近一次分配以来的秒数。在shell启动时,它被初始化为0

您只需在使用令牌之前检查
$SECONDS
的值,如果其值大于1800(30分钟内的秒数),则获取一个新值

SECONDS=1801  # Make sure a token will be generated before the first call
for id in $ids; do
    if [ "$SECONDS" -gt 1800 ]; then
        token
        SECONDS=0
    fi
    ...
done

我解决了这个问题,创建了一个带有状态代码的检查响应

response=$(curl -H 'authorization: '${token_type}' '${bearer_token}'' --write-out '%{http_code}' --silent --output /dev/null https://api.foo.bar/devices/entities/devices/v1?ids='0000000000000')

if [ ${response} -eq 200 ]; then
   do something
else
   token
fi

对于一般用例,我建议在循环结束之前使用外部休眠命令或可加载休眠模块添加minisleep,以避免不必要的CPU使用。@konsolebox您担心哪些不必要的CPU使用?
$SECONDS
的值不是每秒更新一次;当需要它的值时,shell只根据当前时间和上次分配变量时记录的时间戳来计算它。我说的是循环本身,它将无休止地迭代,直到秒被更新。然而,您的循环是有限的,这就是为什么我说“通用用例”,其中循环是无限的。例如((;))的
;做已完成
而:;做完成
。这是为那些找到你的答案并重复使用其概念的人准备的。