Bash wget或curl:格式化进度条
我正在编写这样的更新脚本:Bash wget或curl:格式化进度条,bash,curl,format,wget,pacman-package-manager,Bash,Curl,Format,Wget,Pacman Package Manager,我正在编写这样的更新脚本: update.sh #!/bin/bash sudo echo printf "### PACMAN\n" # I am running Arch Linux sudo pacman -Syu printf "\n### YAY\n" yay -Syua printf "\n### CUSTOM\n" custom_script.sh # code below #!/bin/bash # [...] wget --quiet --show-progr
update.sh
#!/bin/bash
sudo echo
printf "### PACMAN\n" # I am running Arch Linux
sudo pacman -Syu
printf "\n### YAY\n"
yay -Syua
printf "\n### CUSTOM\n"
custom_script.sh # code below
#!/bin/bash
# [...]
wget --quiet --show-progress <some link>
# [...]
#!/bin/bash
source progressbar.sh || exit 1
reformat_and_output_line() {
COLS=()
for val in $1 ; do
COLS+=("$val")
done
if [[ ${#COLS[@]} == 9 ]]; then
RELATIVE_PROGRESS=${COLS[6]%?}
ABSOLUTE_PROGRESS=$(numfmt --from=iec --to=iec-i --format "%.1fB" ${COLS[0]} |
sed 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/')
SPEED=$(printf "%+8s" "${COLS[7]}/s")
TIME=$(printf "%+5s" ${COLS[8]})
progressbar "somefile.txt" "$RELATIVE_PROGRESS" 100 "$ABSOLUTE_PROGRESS" "$SPEED" "$TIME"
elif [[ ${#COLS[@]} == 7 ]]; then
RELATIVE_PROGRESS=${COLS[5]%?}
ABSOLUTE_PROGRESS=$(numfmt --from=iec --to=iec-i --format "%.1fB" ${COLS[0]} |
sed 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/')
SPEED=$(printf "%+8s" "$(echo ${COLS[6]} | cut -d= -f1 )/s")
TIME=$(printf "%+5s" $(echo ${COLS[6]} | cut -d= -f2 ))
progressbar "somefile.txt" "$RELATIVE_PROGRESS" 100 "$ABSOLUTE_PROGRESS" "$SPEED" "$TIME"
fi
}
wget_like_pacman() {
last_output_time=$(( $(date +%s%3N) - 500 ))
wget --quiet --show-progress $1 2>&1 | (
while IFS= read -r line; do
if [[ $(date +%s%3N) > $(( $last_output_time + 500 )) ]]; then
reformat_and_output_line "${line}"
last_output_time=$(date +%s%3N)
fi
done
printf "\r"
reformat_and_output_line "${line}"
echo
)
}
# [...]
wget_like_pacman <some link>
# [...]
custom_script.sh
#!/bin/bash
sudo echo
printf "### PACMAN\n" # I am running Arch Linux
sudo pacman -Syu
printf "\n### YAY\n"
yay -Syua
printf "\n### CUSTOM\n"
custom_script.sh # code below
#!/bin/bash
# [...]
wget --quiet --show-progress <some link>
# [...]
#!/bin/bash
source progressbar.sh || exit 1
reformat_and_output_line() {
COLS=()
for val in $1 ; do
COLS+=("$val")
done
if [[ ${#COLS[@]} == 9 ]]; then
RELATIVE_PROGRESS=${COLS[6]%?}
ABSOLUTE_PROGRESS=$(numfmt --from=iec --to=iec-i --format "%.1fB" ${COLS[0]} |
sed 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/')
SPEED=$(printf "%+8s" "${COLS[7]}/s")
TIME=$(printf "%+5s" ${COLS[8]})
progressbar "somefile.txt" "$RELATIVE_PROGRESS" 100 "$ABSOLUTE_PROGRESS" "$SPEED" "$TIME"
elif [[ ${#COLS[@]} == 7 ]]; then
RELATIVE_PROGRESS=${COLS[5]%?}
ABSOLUTE_PROGRESS=$(numfmt --from=iec --to=iec-i --format "%.1fB" ${COLS[0]} |
sed 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/')
SPEED=$(printf "%+8s" "$(echo ${COLS[6]} | cut -d= -f1 )/s")
TIME=$(printf "%+5s" $(echo ${COLS[6]} | cut -d= -f2 ))
progressbar "somefile.txt" "$RELATIVE_PROGRESS" 100 "$ABSOLUTE_PROGRESS" "$SPEED" "$TIME"
fi
}
wget_like_pacman() {
last_output_time=$(( $(date +%s%3N) - 500 ))
wget --quiet --show-progress $1 2>&1 | (
while IFS= read -r line; do
if [[ $(date +%s%3N) > $(( $last_output_time + 500 )) ]]; then
reformat_and_output_line "${line}"
last_output_time=$(date +%s%3N)
fi
done
printf "\r"
reformat_and_output_line "${line}"
echo
)
}
# [...]
wget_like_pacman <some link>
# [...]
我觉得这听起来很奇怪,但我想你可以用regex解析出wget的响应,然后在将信息打印到控制台之前按照你的意愿重新格式化信息。。。以下是php cli中的概念证明:
#!/usr/bin/env php
<?php
$args = $argv;
unset ( $args [0] );
$args = implode ( " ", array_map ( 'escapeshellarg', $args ) );
$wget_cmd = "wget --quiet --show-progress --progress=bar:force {$args} 2>&1";
$wget = popen ( $wget_cmd, "rb" );
$format = <<<'FORMAT'
%filename% %separator_filename_percent% %total_downloaded% %speed% %eta% %percent_indicator% %percent%%
FORMAT;
$format = trim ( $format );
while ( ! feof ( $wget ) ) {
$line = stream_get_line ( $wget, 4096, "\r" );
$match = preg_match ( '/^(?<filename>.*?)(?<separator_filename_percent>[ ]{3,})(?<percent>\d+)\%(?<percent_indicator>.*?])\s+(?<total_downloaded>\S+)\s+(?<speed>\S+)\s*(?:eta\s*)?(?<eta>.*)?$/', $line, $matches );
if (! $match) {
echo $line;
if (strlen ( $line ) < 4096 && ! feof ( $wget )) {
echo "\r";
}
} else {
// var_dump ( $matches );
echo strtr ( $format, array (
'%filename%' => $matches ['filename'],
'%separator_filename_percent%' => $matches ['separator_filename_percent'],
'%total_downloaded%' => $matches ['total_downloaded'],
'%speed%' => $matches ['speed'],
'%eta%' => $matches ['eta'],
'%percent_indicator%' => str_replace ( "=", "#", $matches ['percent_indicator'] ),
'%percent%' => $matches ['percent']
) ), " ", "\r";
}
// sleep(3);
}
pclose ( $wget );
#/usr/bin/env-php
多亏了提供的链接(),一种与之类似的方法,以及大量的谷歌搜索和反复试验,我想出了以下解决方案:
custom_script.sh
#!/bin/bash
sudo echo
printf "### PACMAN\n" # I am running Arch Linux
sudo pacman -Syu
printf "\n### YAY\n"
yay -Syua
printf "\n### CUSTOM\n"
custom_script.sh # code below
#!/bin/bash
# [...]
wget --quiet --show-progress <some link>
# [...]
#!/bin/bash
source progressbar.sh || exit 1
reformat_and_output_line() {
COLS=()
for val in $1 ; do
COLS+=("$val")
done
if [[ ${#COLS[@]} == 9 ]]; then
RELATIVE_PROGRESS=${COLS[6]%?}
ABSOLUTE_PROGRESS=$(numfmt --from=iec --to=iec-i --format "%.1fB" ${COLS[0]} |
sed 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/')
SPEED=$(printf "%+8s" "${COLS[7]}/s")
TIME=$(printf "%+5s" ${COLS[8]})
progressbar "somefile.txt" "$RELATIVE_PROGRESS" 100 "$ABSOLUTE_PROGRESS" "$SPEED" "$TIME"
elif [[ ${#COLS[@]} == 7 ]]; then
RELATIVE_PROGRESS=${COLS[5]%?}
ABSOLUTE_PROGRESS=$(numfmt --from=iec --to=iec-i --format "%.1fB" ${COLS[0]} |
sed 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/')
SPEED=$(printf "%+8s" "$(echo ${COLS[6]} | cut -d= -f1 )/s")
TIME=$(printf "%+5s" $(echo ${COLS[6]} | cut -d= -f2 ))
progressbar "somefile.txt" "$RELATIVE_PROGRESS" 100 "$ABSOLUTE_PROGRESS" "$SPEED" "$TIME"
fi
}
wget_like_pacman() {
last_output_time=$(( $(date +%s%3N) - 500 ))
wget --quiet --show-progress $1 2>&1 | (
while IFS= read -r line; do
if [[ $(date +%s%3N) > $(( $last_output_time + 500 )) ]]; then
reformat_and_output_line "${line}"
last_output_time=$(date +%s%3N)
fi
done
printf "\r"
reformat_and_output_line "${line}"
echo
)
}
# [...]
wget_like_pacman <some link>
# [...]
#/bin/bash
source progressbar.sh | |出口1
重新格式化_和_输出_行(){
COLS=()
以1美元计价的val;执行
COLS+=(“$val”)
完成
如果[${#COLS[@]}==9]],那么
相对进度=${COLS[6]?}
绝对进度=$(numfmt--from=iec--to=iec-i--format“%.1fB”${COLS[0]}|
sed的/\([^[:blank:]\)\([[:upper:]\)/\1\2/)
速度=$(printf“%+8s”“${COLS[7]}/s”)
时间=$(printf“%+5s”${COLS[8]})
progressbar“somefile.txt”$相对进度“100”$绝对进度“$速度“$时间”
elif[${COLS[@]}==7]];然后
相对进度=${COLS[5]?}
绝对进度=$(numfmt--from=iec--to=iec-i--format“%.1fB”${COLS[0]}|
sed的/\([^[:blank:]\)\([[:upper:]\)/\1\2/)
速度=$(printf“%+8s”“$(echo${COLS[6]}| cut-d=-f1)/s)
时间=$(printf“%+5s”$(echo${COLS[6]}| cut-d=-f2))
progressbar“somefile.txt”$相对进度“100”$绝对进度“$速度“$时间”
fi
}
wget_like_pacman(){
上次输出时间=$($(日期+%s%3N)-500))
wget--安静--显示进度$12>&1|(
当IFS=读取-r行时;执行
如果[[$(日期+%s%3N)>$($last\u output\u time+500))];则
重新格式化_和_输出_行“${line}”
上次输出时间=$(日期+%s%3N)
fi
完成
printf“\r”
重新格式化_和_输出_行“${line}”
回声
)
}
# [...]
吃豆人
# [...]
时间格式并不完全相同,但除此之外,我认为这是相当准确的
还可以省略对最后一次输出时间的if块检查,但是终端会变得疯狂,并且无法实际读取任何值,因为它们更新得太快。可能您需要查看此-。可能正是你想要的need@Inian:非常感谢,正如你在我下面的帖子中看到的那样,这帮了大忙:)不过链接中有一点错误:是罗德哈夫,不是拉奥德哈夫