[bash] select: Auswahlliste updaten in while true-schleife

Twostone

Commodore
Registriert
Dez. 2013
Beiträge
5.113
Hallo.

Als Teil eines Scriptes für wiederkehrende ZFS-Manipulationen stell sich mir folgendes Problem:

In einer select-Schleife (deren Eigenschaften ich mir dank while-Schleife neu anzeigen lassen kann) werden die Elemente der Liste aus einer Variable gebildet. Wenn ich jetzt ein Element verändere, wird dieses jedoch nicht aktualisiert.

Wie wäre dies lösbar?

Codeschnipsel:
Es geht um Manipulation von Dataset-Eigenschaften, hier speziell um Quota.

Code:
[...]
while true; do
[...]
    f_ds_opts(){
        DSOPTSCUR=( $(zfs get all ${DATASET} | grep -iE " compression | dedup | atime | relatime | checksum | quota | refquota | canmount | reservation | refreservation | logbias | recordsize | sharesmb | sharenfs " | awk '{ printf("%-20s%-20s\n",$2,$3) }') )
    }
    OPTIONS=( $(zfs list -r -o name,available,used,referenced,usedsnap,usedds,mounted,compressratio,refcompressratio -s name | tail -n +2) )
     select DATASET in ${OPTIONS
[*]}; do
        if [ ! -z "${DATASET}" ]; then
            DSPS3="${PS3}"
            PS3="Was möchten Sie ändern?"
            DATASET=$(echo ${DATASET} |awk '{ print $1 }')
            echo -e "gewählt: ${RED}${DATASET}${NORMAL}"
            f_ds_opts
            select CHANGE in ${DSOPTSCUR
[*]}; do
                CHANGE=$(echo ${CHANGE} | awk '{print $1}')
                case ${CHANGE} in
                    quota){ #int recursive
                        echo ""
                        echo "Abkürzungen: xK xM xG xT"
                        echo -n "Bitte neue Größe für ${CHANGE} angeben: "
                        read OPT
                        zfs set ${CHANGE}=${OPT} ${DATASET}
                        f_ds_opts
                    }
                    ;;
[...]

geht natürlich noch weiter, funktioniert auch so weit, nur eben, daß die Variable DSOPTSCUR nicht wirklich aktualisiert dargestellt wird, bevor ich den select-loop nicht verlassen und neu aufgerufen habe.

Hat jemand eine Idee, wie man das noch innerhalb des loops aktualisieren könnte?
 
Zuletzt bearbeitet:
[...]
SELECT BLA BLA
[...]
done <( DSOPTSCUR=( $(zfs get all ${DATASET} | grep -iE " compression | dedup | atime | relatime | checksum | quota | refquota | canmount | reservation | refreservation | logbias | recordsize | sharesmb | sharenfs " | awk '{ printf("%-20s%-20s\n",$2,$3) }') ))

Du kannst übergabeparameter am ende der schleife übergeben damit sie im richtigen kontext verstanden werden, da variablen immer im schleifenkontext bleiben
 
Das gibt vor allem einen Syntaxfehler, zumindest in diesem Anwendungsfalle.

edit: Hab mir das noch einmal näher angeschaut, aber im betreffenden Falle kann es nicht funktionieren, ich setze dafür innerhalb der Schleife per Abfrage zu viele andere Variablen. Wenn ich den Parameter tatsächlich übergebe, setzt er schlichtweg alle Variablen und schmeißt dann auch nur noch Fehler.

Hab's letztlich umgeschrieben. Für Snapshots nutze ich bereits eine ähnliche Variante, insofern war das Grundgerüst sowieso schon da. Es ist dann eben keine Dauerschleife mehr, sondern eine Sammlung an Änderungen, die dann übergeben und schrittweise ergänzt und abgearbeitet werden.

Dennoch Danke für Deine Hilfe. Hatte mal wieder etwas dazugelernt, auch wenn es (noch) nicht direkt anwendbar war.

Jetzige Version:
Code:
f_set_opts(){
    SAVEIFS=$IFS
    SETOPTSPS3="$PS3"
    unset CHOICES
    IFS=$(echo -en "\n\b")
    DSOPTIONS=( $(zfs list -r -o name,available,used,referenced,usedsnap,usedds,mounted,compressratio,refcompressratio -s name | tail -n +2) )
    echo "   $(zfs list -o name,available,used,referenced,usedsnap,usedds,mounted,compressratio,refcompressratio | head -n 1)"
    select DATASET in ${DSOPTIONS
[*]}; do
        if [ ! -z "${DATASET}" ]; then
            DATASET=$(echo ${DATASET} |awk '{ print $1 }')
            echo -e "gewählt: ${RED}${DATASET}${NORMAL}"
            OPTIONS=( $(zfs get all ${DATASET} | grep -iE " compression | dedup | atime | relatime | checksum | quota | refquota | canmount | reservation | refreservation | logbias | recordsize | sharesmb | sharenfs " | awk '{ printf("%-20s%-20s\n",$2,$3) }') )
            #sub-fkt
            f_menu() {
                echo "Derzeitige Einstellungen auf ${DATASET}:"
                for i in ${!OPTIONS[@]}; do
                    printf "%3d%s) %s\n" $((i+1)) "${CHOICES[i]:- }" "${OPTIONS[i]}"
                done
                [[ "$MSG" ]] && echo -e "$MSG"; :
            }
            #end sub-fkt
            clear
            echo ""
            PROMPT="Wählen Sie die zu ändernden Optionen (erneut zum abwählen, ENTER zum beenden): "
            while clear && echo "" && f_menu && read -rp "${PROMPT}" NUM && [[ "${NUM}" ]]; do
                [[ "${NUM}" != *[![:digit:]]* ]] && (( NUM > 0 && NUM <= ${#OPTIONS[@]} )) || {
                    MSG="ungülgige Auswahl: ${NUM}"; continue
                }
                ((NUM--)); MSG="${BLUE}$(echo ${OPTIONS[NUM]}| awk '{print $1}') ${NORMAL}wurde ${CHOICES[NUM]:+ab}gewählt"
                [[ "${CHOICES[NUM]}" ]] && CHOICES[NUM]="" || CHOICES[NUM]="+"
            done

            printf "Ausgewählte Optionen: "; MSG="Keine."
            for i in ${!OPTIONS[@]}; do
                [[ "${CHOICES[i]}" ]] && { printf " %s" "$(echo ${OPTIONS[i]} |awk '{print $1}')"; MSG=""; }
            done
            echo "${MSG}"

            if [ ! "${MSG}" = "Keine." ]; then
                f_yesno
                if [ "${YESNO}" = "YES" ]; then
                    for i in ${!OPTIONS[@]}; do
                        if [[ "${CHOICES[i]}" ]]; then
                            CHANGE=$(echo ${OPTIONS[i]} |awk '{print $1}')
                            case ${CHANGE} in
                                compression){ # on | off | lzjb | gzip | gzip-N | zle | lz4
                                    PARAM=( on off lzjb gzip gzip-9 zle lz4 )
                                    f_opts_string
                                }
                                ;;
                                dedup){ #on | off | verify | sha256[,verify]
                                    PARAM=( on off verify )
                                    f_opts_string
                                }
                                ;;
                                atime){ #BOOL
                                    PARAM=( on off )
                                    f_opts_string
                                }
                                ;;
                                relatime){ #BOOL wenn atime
                                    PARAM=( on off )
                                    f_opts_string
                                }
                                ;;
                                checksum){ #on | off | fletcher2,| fletcher4 | sha256
                                    PARAM=( on off fletcher2 fletcher4 sha256 )
                                    f_opts_string
                                }
                                ;;
                                canmount){ #on | off | noauto
                                    PARAM=( on off noauto )
                                    f_opts_string
                                }
                                ;;
                                logbias){ # latency | throughput
                                    PARAM=( latency throughput )
                                    f_opts_string
                                }
                                ;;
                                recordsize){ #512 1k 2k 4k 16k 64k 128k
                                    echo "Option derzeit nicht implementiert"
                                    break
                                }
                                ;;
                                sharesmb){ #BOOL
                                    PARAM=( on off )
                                    f_opts_string
                                }
                                ;;
                                sharenfs){ #BOOL
                                    PARAM=( on off )
                                    f_opts_string
                                }
                                ;;
                                quota){ #int recursive
                                    f_opts_int
                                }
                                ;;
                                refquota){ #int DS only
                                    f_opts_int
                                }
                                ;;
                                reservation){ #int recursive
                                    f_opts_int
                                }
                                ;;
                                refreservation){ #int DS only
                                    f_opts_int
                                }
                                ;;
                            esac
                        fi
                    done
                    break
                else
                    echo "abgebrochen."
                    break
                fi
            fi
        fi
        break
    done
    IFS=$SAVEIFS
    PS3="${SETOPTSPS3}"
    }
 
Zuletzt bearbeitet:
Zurück
Oben