首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获得流行的拱形包

获得流行的拱形包
EN

Code Review用户
提问于 2021-08-06 21:33:43
回答 3查看 83关注 0票数 4

获得一个流行的Arch软件包的列表,其受欢迎程度高于或等于给定的软件包。

如果不给的话,它就要求受欢迎。然后获取包的总数并进行迭代,直到得到整个包的列表--每次1000次,因为如果我试图获取它们,所有的API都会出现错误。

代码语言:javascript
复制
#!/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 "$@"
EN

回答 3

Code Review用户

回答已采纳

发布于 2021-08-07 10:10:57

您可能应该解决这些Shellcheck问题:

代码语言:javascript
复制
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"

使用它的内部流水线更有效:

代码语言:javascript
复制
        | jq ".packagePopularities[] | select(.popularity >= $popularity) | .name"

这就省去了程序不得不在中间两次序列化和反序列化数据。

没有必要存储这样的结果:

packages=() while;do packages+=$(命令…)回音"${packages}“

我们可以简单地打印:

代码语言:javascript
复制
while [ $x -le $total ]; do
    command …
done

这意味着我们不需要任何Bash功能,而是可以编写一个可移植的(POSIX) shell脚本。这很可能在操作上更精简(例如,如果system shell是Dash,这比Bash低得多)。

main函数将get_popular_packages的输出捕获到变量中,但没有将其用于任何事情就完成了它。我希望更像是

代码语言:javascript
复制
popularity=$(get_popularity "$@")
get_popular_packages $(get_total_pkgs) $popularity
票数 2
EN

Code Review用户

发布于 2021-08-07 02:09:43

首先,作为一个写了很多bash的人,我建议用bash以外的东西重写它。您正在使用bash作为编程语言(并且非常努力地使其可读性),但它根本不是最好的编程语言。

  • 将一堆curl和jq命令粘合在一起的基本想法似乎很牢固。
  • 我会联系API的维护者,并礼貌地要求他们记录API限制或删除它。
  • 在一行末尾重复使用\,在下一行中使用|。相反,只需将|放在第一行的末尾即可。
  • 分离出获取所有API响应(get_all_package_json)和限制流行响应(get_popular_packages)的逻辑。jq每行可以接受一个JSON对象。
  • 为了避免错误和方便用户,我建议通过sort -u输出包。
票数 2
EN

Code Review用户

发布于 2021-08-07 17:12:48

建议实施后。没有人建议停止下载,当软件包比给定的受欢迎程度较低。

代码语言:javascript
复制
#!/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 "$@"
票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/265799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档