shell脚本中的数组函数出现问题

pgky5nke  于 2022-11-16  发布在  Shell
关注(0)|答案(3)|浏览(193)

我正在尝试创建一个小的shell脚本函数,基本上它只返回github仓库的两个最新版本(不包括最新版本)。

get_release() {
curl --silent \
  -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/user/repo/releases |
  grep '"tag_name":' |
  sed -E 's/.*"([^"]+)".*/\1/' 
}

#str="1.1.1 2.2.2 3.3.3 4.4.4 5.5.5 6.6.6 7.7.7 8.8.8 9.9.9"
str=($get_release)

#VERSION=$(get_release)
IFS=', ' read -r -a array <<< "$str"

LASTVERSION=${array[-2]}
PENULTIMATEVERSION=${array[-3]}

echo "${LASTVERSION}"
echo "${PENULTIMATEVERSION}"

但我试着跑的时候却发现了这个:

t.sh: line 17: array: bad array subscript
t.sh: line 18: array: bad array subscript

注意:注解的str变量只是一个数组的模拟,它工作正常,但是当尝试使用get_release函数时,我得到了这个错误。

rqcrx0a6

rqcrx0a61#

以下是一个与3.2及更高版本的所有bash版本兼容的工作示例:

get_releases() {
  local user=$1 repo=$2
  curl --silent \
    -H "Accept: application/vnd.github.v3+json" \
    "https://api.github.com/repos/$user/$repo/releases" |
    jq -r '.[].tag_name'
}

IFS=$'\n' read -r -d '' -a releases < <(get_releases juji-io datalevin && printf '\0')
echo "Newest release: ${releases[0]}"
echo "Oldest release: ${releases[${#releases[@]}-1]}"
echo "Second oldest:  ${releases[${#releases[@]}-2]}"

...到目前为止正确发出的项目(对于上例中使用的juji-io/datalevin项目):

Newest release: 0.6.6
Oldest release: 0.5.13
Second oldest:  0.5.14
cnwbcb6i

cnwbcb6i2#

根据@Philippe的注解,($get_release)不会调用您的函数,但$(get_release)会。
根据@Charles Duffy和@glenn jackman对的评论,我更新了代码片段,以便安全地检查和访问数组的最后一个元素。
下面是修改后的代码片段:

get_release() {
curl --silent \
  -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/user/repo/releases |
  grep '"tag_name":' |
  sed -E 's/.*"([^"]+)".*/\1/' 
}

# str=($get_release) # Warning: this does not call get_release
# str='1.1.1 2.2.2 3.3.3 4.4.4 5.5.5 6.6.6 7.7.7 8.8.8 9.9.9'
str=$(get_release)

IFS=', ' read -r -a array <<< "$str"

n=${#array[@]}
((n > 1)) && LASTVERSION=${array[$((n-1))]}
((n > 2)) && PENULTIMATEVERSION=${array[$((n-2))]}

echo "${LASTVERSION}" # 9.9.9
echo "${PENULTIMATEVERSION}" # 8.8.8

下面是另一个基于perl、regex和捕获组的解决方案,即

# str=($get_release) # Warning: this does not call get_release
# str='1.1.1 2.2.2 3.3.3 4.4.4 5.5.5 6.6.6 7.7.7 8.8.8 9.9.9'
str=$(get_release)
LASTVERSION=$(perl -ne 'print if s/.* (\d+\.\d+\.\d+)/\1/' <<< $str)
PENULTIMATEVERSION=$(perl -ne 'print if s/.* (\d+\.\d+\.\d+) \d+\.\d+\.\d+/\1/' <<< $str)

echo "${LASTVERSION}" # 9.9.9
echo "${PENULTIMATEVERSION}" # 8.8.8
ghhkc1vu

ghhkc1vu3#

感谢每一个帮助我的人,我能够这样解决它:

get_release() {
curl --silent \
  -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/user/repo/releases |
  grep '"tag_name":' |
  sed -E 's/.*"([^"]+)".*/\1/' 
}

CREATE_ARRAY=$'\n' read -d "\034" -r -a array <<< "$(get_branch)\034" # See: https://unix.stackexchange.com/questions/628527/split-string-on-newline-and-write-it-into-array-using-read

PENULTIMATE_VERSION="${array[2]}"
ANTIPENULTIMATE_VERSION="${array[1]}"

相关问题