我有一些看起来像的秒表脚本:
BEGIN=$(date +%s)
while true; do
NOW=$(date +%s)
DIFF=$(($NOW - $BEGIN))
MINS=$(($DIFF / 60))
SECS=$(($DIFF % 60))
HOURS=$(($DIFF / 3600))
# \r is a "carriage return" - returns cursor to start of line
printf "\rDownload time: %02d:%02d:%02d" $HOURS $MINS $SECS
sleep 1
done
所以while
某些条件为真,它会在每个循环中增加1秒。我希望这种情况有所不同:
function download()
{
HOMEPAGE_RESPONSE=$(curl -w "\n%{http_code}" "https://example.com/")
STATUS_CODE=$(echo "$HOMEPAGE_RESPONSE" | sed -n '$p')
HTML=$(echo "$HOMEPAGE_RESPONSE" | sed '$d')
}
download
# Whenever the STATUS_CODE is 200, exit the stopwatch script
# Can be any other condition that stops the loop when cURL has finished
while (( $STATUS_CODE != 200 )); do
NOW=$(date +%s)
DIFF=$(($NOW - $BEGIN))
MINS=$(($DIFF / 60))
SECS=$(($DIFF % 60))
HOURS=$(($DIFF / 3600))
# \r is a "carriage return" - returns cursor to start of line
printf "\rDownload time: %02d:%02d:%02d" $HOURS $MINS $SECS
sleep 1
done
想法是启动cURL下载并在下载开始的同时执行秒表脚本。这将最终开始计算秒数并打印秒表until
下载完成。我也知道我在post中找到的until
命令。例如:
until $(curl --output /dev/null --silent --head --fail http://myhost:myport); do
printf '.'
sleep 5
done
我不知道如何应用until
,因为我的cURL存储在名为download()
的函数中的变量中,我希望能够使用STATUS_CODE
和{ {1}}内容分开。
谁能告诉我怎么做?
更新
鉴于@Inian的回答,这是我到目前为止所做的:
HTML
根据我的理解,这应该执行功能function download()
{
homepage_response=$(curl -s -w "\n%{http_code}" "https://example.com/")
status_code=$(echo "$homepage_response" | sed -n '$p')
html=$(echo "$homepage_response" | sed '$d')
printf '%s' "${status_code}"
}
# Calling the function $(download)
until [[ "$(download)" == "200" ]]; do
printf '.\n'
sleep 1
done
echo $status_code
并在不同的行download()
上打印.
cURL返回until
的{{1}}。
然而,这会启动cURL,但它既不会打印status_code
也不会回显200
,它应该等同于.
。
我无法猜到为什么。
更改回答
根据@chepner的回答,我提出了:
status_code
出于预防措施,我添加了200
,只要脚本在最后执行download()
{
homepage_response=$(curl -s -w "\n%{http_code}" "https://example.com/")
status_code=$(echo "$homepage_response" | sed -n '$p')
html=$(echo "$homepage_response" | sed '$d')
# printf '%s' "${status_code}"
}
start_stopwatch () {
BEGIN=$(date +%s)
while true; do
NOW=$(date +%s)
DIFF=$(($NOW - $BEGIN))
MINS=$(($DIFF / 60))
SECS=$(($DIFF % 60))
HOURS=$(($DIFF / 3600))
printf "\rDownload time: %02d:%02d:%02d" "$HOURS" "$MINS" "$SECS"
sleep 1 & wait # Make it interruptible
done
}
start_stopwatch & sw_pid=$!
# # For testing purposes
# echo "$sw_pid"
# Kill background stopwatch if script EXITS beforehand
set -e
kill_sw() {
kill "$sw_pid"
}
trap kill_sw EXIT
# Call function download()
download
printf "\n"
kill "$sw_pid"
之前被中断,就会调用函数set -e
。
答案 0 :(得分:1)
您只需要将函数调用用于until
条件。但是当前状态下的函数download()
不会打印状态代码的输出。稍作修改如下。
download() {
homepage_response=$(curl -w "\n%{http_code}" "https://example.com/")
status_code=$(echo "$HOMEPAGE_RESPONSE" | sed -n '$p')
html=$(echo "$HOMEPAGE_RESPONSE" | sed '$d')
printf '%s' "${status_code}"
}
现在使用打印状态代码的功能,在条件为
中使用它until [[ "$(download)" -eq "$(curl --output /dev/null --silent --head --fail http://myhost:myport)" ]]; do
sleep 1
# Your rest of the script goes here
done
作为一般编码实践,
((..))
构造let
bash
系统特定的环境变量冲突。function
- isms时,建议使用不带bash
关键字的函数定义。答案 1 :(得分:1)
我会在后台运行秒表代码,并在curl
完成后将其终止。
start_stopwatch () {
SECONDS=0
while true; do
now=$SECONDS
hours=$((now / 3600))
now=$((now % 3600))
mins=$((now / 60))
secs=$((now % 60))
printf "\rDownload time: %02d:%02d:%02d" "$hours" "$mins" "$secs"
sleep 1
done
}
start_stopwatch & sw_pid=$!
curl ...
kill "$sw_pid"