获得一个流行的Arch软件包的列表,其受欢迎程度高于或等于给定的软件包。
如果不给的话,它就要求受欢迎。然后获取包的总数并进行迭代,直到得到整个包的列表--每次1000次,因为如果我试图获取它们,所有的API都会出现错误。
#!/usr/bin/env bash
function get_popularity() {
local popularity
if [ $# -gt 0 ]; then
popularity=$1
else
read -rp "Popularity [0-100]: " popularity
fi
while [[ $popularity -lt 0 || $popularity -gt 100 ]] ; do
read -rp "Popularity [0-100]: " popularity
done
echo $popularity
}
function get_total_pkgs() {
local total
total=$(curl -sX "GET" -H "accept: application/json" \
"https://pkgstats.archlinux.de/api/packages?limit=1&offset=0" \
| jq ".total")
echo $total
}
function get_popular_packages() {
local x total popularity packages limit
total=$1
popularity=$2
packages=()
x=0
limit=1000
while [ $x -le $total ]; do
packages+=$(curl -sX "GET" -H "accept: application/json" \
"https://pkgstats.archlinux.de/api/packages?limit=$limit&offset=$x" \
| jq ".packagePopularities[]" \
| jq "select( .popularity >= $popularity )" \
| jq ".name")
x=$(($x+$limit))
done
echo "${packages[@]}"
}
function main () {
popularity=$(get_popularity "$@")
packages=$(get_popular_packages $(get_total_pkgs) $popularity)
}
main "$@"发布于 2021-08-07 10:10:57
您可能应该解决这些Shellcheck问题:
265799.sh:32:9: warning: Use array+=("item") to append items to an array. [SC2179]
265799.sh:37:14: note: $/${} is unnecessary on arithmetic variables. [SC2004]
265799.sh:37:17: note: $/${} is unnecessary on arithmetic variables. [SC2004]
265799.sh:44:5: warning: Variable was used as an array but is now assigned a string. [SC2178]
265799.sh:44:37: warning: Quote this to prevent word splitting. [SC2046]
265799.sh:44:55: note: Double quote to prevent globbing and word splitting. [SC2086]实现与描述不匹配。“受欢迎程度大于或等于给定的”意味着我们要给一个包名作为参数,但是程序需要一个数字。我猜这是描述中的一个错误,但它强调了在程序文档(经常被忽略的一个方面)中明确和明确的必要性。
如果参数丢失,我不喜欢要求输入的命令--我更喜欢一个清晰的错误消息,显示如何正确地使用该命令。这使得调试它在脚本中的使用变得更容易,例如。
没有必要在管道中使用jq的三次调用:
| jq ".packagePopularities[]" \ | jq "select( .popularity >= $popularity )" \ | jq ".name"
使用它的内部流水线更有效:
| jq ".packagePopularities[] | select(.popularity >= $popularity) | .name"这就省去了程序不得不在中间两次序列化和反序列化数据。
没有必要存储这样的结果:
packages=() while;do packages+=$(命令…)回音"${packages}“
我们可以简单地打印:
while [ $x -le $total ]; do
command …
done这意味着我们不需要任何Bash功能,而是可以编写一个可移植的(POSIX) shell脚本。这很可能在操作上更精简(例如,如果system shell是Dash,这比Bash低得多)。
main函数将get_popular_packages的输出捕获到变量中,但没有将其用于任何事情就完成了它。我希望更像是
popularity=$(get_popularity "$@")
get_popular_packages $(get_total_pkgs) $popularity发布于 2021-08-07 02:09:43
首先,作为一个写了很多bash的人,我建议用bash以外的东西重写它。您正在使用bash作为编程语言(并且非常努力地使其可读性),但它根本不是最好的编程语言。
\,在下一行中使用|。相反,只需将|放在第一行的末尾即可。get_all_package_json)和限制流行响应(get_popular_packages)的逻辑。jq每行可以接受一个JSON对象。sort -u输出包。发布于 2021-08-07 17:12:48
建议实施后。没有人建议停止下载,当软件包比给定的受欢迎程度较低。
#!/usr/bin/env bash
function usage() {
cat <= $1 )" \
| jq ".name"
}
function get_popular_packages() {
local x total limit
popularity=$(get_popularity "$@")
total=$(get_total_packages)
x=0
limit=2000
while [ $x -le $total ]; do
get_packages $popularity $limit $x
x=$(($x+$limit))
done
}
get_popular_packages "$@"https://codereview.stackexchange.com/questions/265799
复制相似问题