En mi script en bash, hay muchas variables y tengo que hacer algo para guardarlas en un archivo. Mi pregunta es cómo enumerar todas las variables declaradas en mi script y obtener una lista como esta:
VARIABLE1=abc
VARIABLE2=def
VARIABLE3=ghi
set
generará las variables, desafortunadamente también generará las funciones definidas.
Afortunadamente, el modo POSIX solo genera las variables:
( set -o posix ; set ) | less
Conectando less
o redireccionando a donde quieras las opciones.
Entonces, para obtener las variables declaradas solo en el script:
( set -o posix ; set ) >/tmp/variables.before
source script
( set -o posix ; set ) >/tmp/variables.after
diff /tmp/variables.before /tmp/variables.after
rm /tmp/variables.before /tmp/variables.after
(O al menos algo basado en eso :-))
-o posix
ahora un diff solo contendrá las variables.VARS="`set -o posix ; set`"; source script; SCRIPT_VARS="`grep -vFe "$VARS" <<<"$(set -o posix ; set)" | grep -v ^VARS=`"; unset VARS;
. Esto también generará las variables en un formato listo para guardar. La lista incluirá las variables que el guión cambiado (que depende de si esto es deseable)source
, debería poder hacerlo con la salida dedeclare -p
.before=$(set -o posix; set); dosomestuff; diff <(echo "$before") <(set -o posix; set)
Enumera todas las variables, incluidas las locales. Lo aprendí de Obtener la lista de variables cuyo nombre coincide con un patrón determinado y lo usé en mi script .
fuente
compgen -v
también enumera las variables globales que no se establecieron localmente. No estoy seguro de si se trata de un error de larga data o del comportamiento deseado.Esto debe imprimir todos los nombres de las variables de shell. Puede obtener una lista antes y después de obtener su archivo al igual que con "set" para diferenciar qué variables son nuevas (como se explica en las otras respuestas). Pero tenga en cuenta que dicho filtrado con diff puede filtrar algunas variables que necesita pero que estaban presentes antes de obtener su archivo.
En su caso, si sabe que los nombres de sus variables comienzan con "VARIABLE", entonces puede obtener su script y hacer:
ACTUALIZACIÓN: Para una solución BASH pura (no se utilizan comandos externos):
fuente
eval "printf '%q\n' $(printf ' "${!%s@}"' _ {a..z} {A..Z})"
Según algunas de las respuestas anteriores, esto funcionó para mí:
archivo fuente :
fuente
Si puede posprocesar (como ya se mencionó), puede realizar una
set
llamada al principio y al final de su script (cada uno a un archivo diferente) y hacer una diferencia en los dos archivos. Tenga en cuenta que esto todavía contendrá algo de ruido.También puede hacer esto programáticamente. Para limitar la salida a su alcance actual, tendría que implementar un contenedor para la creación de variables. Por ejemplo
Cuyos rendimientos
fuente
Aquí hay algo similar a la respuesta de @GinkgoFr, pero sin los problemas identificados por @Tino o @DejayClayton, y es más robusto que el
set -o posix
bit inteligente de @ DouglasLeeder :La diferencia es que esta solución SE DETIENE después del primer informe no variable, por ejemplo, la primera función informada por
set
Por cierto: El problema de "Tino" está resuelto. Aunque POSIX está desactivado y las funciones son informadas por
set
, lased ...
parte de la solución solo permite informes variables (por ejemplo,VAR=VALUE
líneas). En particular, noA2
aparece de forma falsa en la salida.Y: El problema "DejayClayton" está resuelto (las líneas nuevas incrustadas en los valores de las variables no interrumpen la salida; cada
VAR=VALUE
una obtiene una única línea de salida):NOTA: La solución proporcionada por @DouglasLeeder sufre el problema "DejayClayton" (valores con nuevas líneas incrustadas). A continuación,
A1
está mal yA2
no debería mostrarse en absoluto.FINALMENTE: No creo que la versión sea
bash
importante, pero podría. Hice mis pruebas / desarrollo en este:POST-SCRIPT: Dadas algunas de las otras respuestas al OP, me queda <100% seguro de que
set
siempre convierte nuevas líneas dentro del valor al\n
que se basa esta solución para evitar el problema "DejayClayton". ¿Quizás ese sea un comportamiento moderno? ¿O una variación en tiempo de compilación? O unaset -o
oshopt
ajuste de la opción? Si usted sabe de tales variaciones, por favor añadir un comentario ...fuente
Intente usar un script (llamémoslo "ls_vars"):
chmod + x it, y:
fuente
Desde una perspectiva de seguridad, ya sea de @ akostadinov respuesta o @ de JuvenXu respuesta es preferible confiar en la salida no estructurada del
set
mando, debido a lo siguiente falla de seguridad potencial:La función anterior se
doLogic
utilizaset
para verificar la presencia de una variablePS1
para determinar si el script es interactivo o no (no importa si esta es la mejor manera de lograr ese objetivo; esto es solo un ejemplo).Sin embargo, la salida de
set
no está estructurada, lo que significa que cualquier variable que contenga una nueva línea puede contaminar totalmente los resultados.Esto, por supuesto, es un riesgo potencial para la seguridad. En su lugar, use el soporte de Bash para la expansión indirecta de nombres de variables o
compgen -v
.fuente
Pruebe esto:
set | egrep "^\w+="
(con o sin la| less
tubería)La primera solución propuesta
( set -o posix ; set ) | less
, funciona pero tiene un inconveniente: transmite códigos de control al terminal, por lo que no se visualizan correctamente. Entonces, por ejemplo, si hay (probablemente) unaIFS=$' \t\n'
variable, podemos ver:…en lugar.
Mi
egrep
solución muestra esto (y eventualmente otros similares) correctamente.fuente
bash -c $'a() { echo "\nA=B"; }; unset A; set | egrep "^\w+="' | grep ^A
pantallas incorrectasA=B"
-> ¡Falla!Probablemente he robado la respuesta hace un tiempo ... de todos modos, un poco diferente como función:
fuente
El
printenv
comando:printenv
imprime todoenvironment variables
junto con sus valores.Buena suerte...
fuente
Una forma sencilla de hacer esto es usar el modo estricto bash configurando las variables de entorno del sistema antes de ejecutar su script y usar diff para ordenar solo las de su script:
Ahora puede recuperar variables de su script en /tmp/script_vars.log. ¡O al menos algo basado en eso!
fuente
Un poco tarde para la fiesta, pero aquí hay otra sugerencia:
La línea de comando diff + sed pipeline genera todas las variables definidas por script en el formato deseado (como se especifica en la publicación del OP):
fuente