Shell-Script

如何從使用者那裡獲取多個輸入並轉換為查找值並將它們添加到變數的字元串?

  • July 2, 2021

我有一個腳本,它接受使用者的輸入(選項 1、2、3 等)來選擇要部署到遠端伺服器的文件。而不是使用者多次執行此腳本,我希望他們能夠輸入多個選項(例如 2,3),因此,這些條目會將文本添加到一個變數中,然後在主函式中引用該變數.

我已經嘗試將這些相加並讓輸入與總和相匹配,但是,如果我們有很多工件要放在這個列表中,選項 5 將部署一個東西,選項 2,3 將部署不同,但加在一起將部署與選項 5 相同這是不可接受的。

例如,這是我目前設置的內容,我只是匹配使用者輸入的字元串(刪除空格後,如果有的話)並執行該選項。這僅適用於 2 或 3 個工件,但是,當列表變長時,選擇會成倍增加。

#!/bin/sh

export alltags="all"
export tag1="artifact1"
export tag2="artifact2"
export tag3="artifact3"

deployment_tag=""

function updateArtifacts

{
  cp -r /path/to/artifact/artifact.zip --tags "\"${deployment_tag}"\"
}

echo "Enter the number of the artifacts you would like to deploy"
"1. artifact1"
"2. artifact2"
"3. artifact3"

read -p " " num

trimNum=`echo $num | sed 's/ //g'`

if [ "$trimNum" == "1" ]; then
      $deployment_tag+="$alltags"
      echo "Updating all artifacts"
      updateArtifacts
elif [ "$trimNum" == "2" ]; then
      $deployment_tag+="$tag1"
      echo "Updating artifact 1"
      updateArtifacts
elif [ "$trimNum" == "2,3" ]; then
      $deployment_tag+="$tag1,$tag2"
      echo "Updating artifact 1 and 2"
      updateArtifacts
else
    echo "aborted, please enter a valid selection"
fi

我知道我缺少選項,但這只是舉一個簡短的例子。我知道這很囉嗦,我很感激任何意見。

以下是如何使用數組執行此操作的範例,並且可以選擇從命令行獲取 args。如果沒有提供參數,則提示輸入工件標籤。

我最終沒有使用case語句,因為事實證明,通過將所有標籤放入數組中,就不需要了。

#!/bin/bash

# dup stdout so we can print prompts etc in the ask function
# anything printed to >&3 will go to the terminal (i.e. original stdout)
# anything printed to stdout will be part of the function's return value
exec 3>&1

tags=( all
artifact1  artifact2  artifact3
artifact4  artifact5  artifact6
artifact7  artifact8  artifact9
artifact10 artifact11 artifact12
artifact13 artifact14 artifact15
)
declare -a deployment_tags
declare -a nums

# comment out or set to zero to disable debugging
debug=1

[ "$debug" = 1 ] && declare -p tags deployment_tags nums

###
### functions
###

print_choices() {
 i=1
 while [ "$i" -lt "${#tags[@]}" ] ; do
   # one per line
   #printf '%i. %s\n' "$i" "${tags[$i]}" >&3
   #let i=i+1

   # or three per line
   for j in 0 1 2; do
     [ -n "${tags[$i]}" ] && printf '%2i. %-12s\t' "$i" "${tags[$i]}" >&3
     let i=i+1
   done
   printf "\n" >&3

 done
}

usage() {
  echo "Usage: $(basename "$0") [n...]"
  echo
  print_choices
  echo "Choose 1 or more, separated by spaces or commas, or 0 for all of the above"
  exit 1;
}

ask() {
 echo "Enter the number of the artifacts you would like to deploy:" >&3
 print_choices
 echo "Choose 1 or more, separated by spaces or commas, 0 for all, or q to quit" >&3

 until [[ "$num" =~ ^[[:space:]0-9,qQ]+$ ]] ; do
   read -r -p "Choose: " num >&3

   [[ $num =~ [qQ] ]] && return 1

   # split into nums array.  if num contains zero ("all"), remove
   # all other choices as they're already included in "all"
   nums=( $(printf '%s' "$num" | sed -e 's/.*0.*/0/; s/,/ /g') )

   # if any of the numbers provided didn't correspond to a valid
   # tag, ask again
   for i in "${nums[@]}" ; do
     [ -z "${tags[$i]}" ] && echo "Invalid choice $i" >&3 && num=""
   done
 done

 echo "${nums[@]}"
}

updateArtifacts() {
  # WTF is the `--tags` argument to `cp`???
  # echo it because it's bogus
  echo cp -r /path/to/artifact/artifact.zip --tags "$@"

 # this function should do something useful with "$@".
}

###
### main code
###

# get the args from the command line, or ask for them if missing.
if [ -n "$*" ] ; then
 # only digits separated by commas or spaces allowed
 [[ "$*" =~ ^[[:space:]0-9,]+$ ]] || usage

 # split into nums array.  if num contains zero ("all"), remove
 # all other choices as they're already included in "all"
 nums=( $(printf '%s' "$*" | sed -e 's/.*0.*/0/; s/,/ /g') )
else
 nums=( $(ask) )
 [ "$?" != 0 ] && echo "Quitting..." && exit 0
fi

[ "$debug" = 1 ] && declare -p nums

# get nums choices into deployment_tags array
for i in "${nums[@]}" ; do
 [ -z "${tags[$i]}" ] && echo "Error: tag $i does not exist!" && exit 2

 deployment_tags+=("${tags[$i]}")
done

[ "$debug" = 1 ] && declare -p deployment_tags

updateArtifacts "${deployment_tags[@]}"

引用自:https://unix.stackexchange.com/questions/656587