Sono sicuro che è relativamente semplice, semplicemente non so come farlo.
#!/usr/bin/ksh
set `iostat`
myvar=6
Voglio qualcosa come quello echo ${$myvar}
che voglio interpretato come ${$myvar}
-> ${6}
->value
Sono sicuro che è relativamente semplice, semplicemente non so come farlo.
#!/usr/bin/ksh
set `iostat`
myvar=6
Voglio qualcosa come quello echo ${$myvar}
che voglio interpretato come ${$myvar}
-> ${6}
->value
Risposte:
Puoi farlo con eval
, integrato in molte belle shell, tra cui ksh:
#!/usr/bin/ksh
set $(iostat)
myvar=6
eval "echo \${$myvar}"
Il trucco è di citare due volte la stringa con cui ti nutri in eval
modo che $ myvar venga sostituito con "6", e di rovesciare il segno del dollaro esterno, in modo da eval
ottenere una stringa "$ 6".
Ho ottenuto "% user" per l'output, ma l'ho provato su una macchina RHEL multi-processore.
vv=$( eval "echo \$$vn" )
. Grazie mille!
Le moderne shell avanzate hanno un metodo per fare riferimento al valore di una variabile il cui nome è memorizzato in un'altra variabile. Sfortunatamente il metodo differisce tra ksh, bash e zsh.
In mksh ≥R39b, puoi creare myvar
una nameref:
typeset -n myvar=6
echo "$myvar"
Questo non funziona in ATT ksh93 perché non supporta namerefs ai parametri posizionali. Nel caso in cui si disponga di una variabile contenente un nome variabile, è possibile utilizzare questo metodo.
foo=bar
typeset -n myvar=foo
echo "$myvar" # prints bar
In bash ≥2.0, è possibile scrivere
echo "${!myvar}"
In zsh, puoi scrivere
echo ${(P)myvar}
Nelle shell più vecchie, inclusi ksh88 e pdksh, l'unica soluzione è quando hai una variabile che contiene un altro nome di variabile e vuoi usare il valore di questa variabile eval
, come spiegato da Bruce Ediger . Questa soluzione funziona in qualsiasi shell Bourne / POSIX.
eval "value=\${$myvar}"
echo "$value"
Questo è il metodo migliore qui: è più semplice e portatile.
Per il tuo caso d'uso, in qualsiasi shell con array (tutte le varianti di ksh, bash ≥2.0, zsh), puoi assegnare a una variabile array e prendere l'elemento che desideri. Attenzione che le matrici ksh e bash iniziano la numerazione da 0, ma zsh inizia da 1 a meno che non si emetta setopt ksh_arrays
o emulate ksh
.
set -A iostat -- $(iostat)
echo "${iostat[5]}"
Se si desidera copiare i parametri posizionali in una variabile di matrice a
:
set -A a -- "$@"
In ksh93, mksh ≥R39b, bash ≥2,0 e zsh, è possibile utilizzare la sintassi dell'assegnazione dell'array:
iostat=($(iostat))
echo "${iostat[5]}"
eval "vv=\${$vn}"
. Merci beaucoup, gentile signore.
Come indicato da Gilles (che ha fornito la bash
parte della risposta), anche non invalidando Bruce Ediger (su come farlo in modo portabile con eval
), ecco come farlo con nameref
di recente mksh
(e AT&T ksh93, tranne - come ha commentato @Gilles - namerefs non può fare riferimento a parametri posizionali in AT&T ksh, solo a parametri nominati):
#!/bin/mksh
set -- $(iostat)
nameref myvar=6
echo $myvar
Aggiunto anche il --
dopo set
per migliorare la resistenza.
typeset: 6: invalid variable name
).
Non ho usato né ksh né alcuna variante per qualche tempo, quindi non sono sicuro se ksh (o bash) abbia una capacità simile. La mia shell principale è zsh. Uso le matrici quando gestisco l'output da comandi come iostat perché producono più righe e non tutte le linee hanno lo stesso formato / lunghezza.
#! /bin/zsh
IOStatOutput=("${(@f)$(iostat)}") # Produces one element per line
Quanto sopra ignora anche l'uso di parametri posizionali. Ora, se vuoi generare, diciamo, un array di dispositivi:
for Element in {7..${#IOStatOutput}} # Devices listed in elements 7 thru the last
do
DevList+=( ${${=IOStatOutput[Element]}[1]} )
done
Trovo blocchi più piccoli molto più facili da gestire. Potrebbe essere necessario o meno utilizzare il riferimento alla variabile indiretta, a seconda del codice. Sapere come funziona è ancora una buona cosa da sapere. Lo uso da solo.