El comando bash builtin set
, si se invoca sin argumentos, imprimirá todas las variables de entorno y shell, pero también todas las funciones definidas. Esto hace que la salida sea inutilizable para los humanos y difícil grep
.
¿Cómo puedo hacer que el comando bash builtin set
imprima solo las variables y no las funciones?
¿Hay otros comandos que imprimen solo las variables de shell, sin las funciones?
Nota: bash diferencia entre las variables de shell y las variables de entorno. ver aquí Diferencia entre variables de entorno y variables de entorno exportadas en bash
fuente
_
, que son fáciles de eliminar:(set -o posix ; set | grep -v ^_)
set -o posix; set | sed -e '/^_/,$d'; set +o posix;
(set -o posix; set)
. Sin los corchetes, el comportamiento del shell Bash actual se cambiaría para que coincida con el estándar Posix. (No sé qué significa eso, pero parece importante.) Con los corchetes, el Bash permanece sin cambios.POSIXLY_CORRECT=y
y agregaposix
a$SHELLOPTS
Aquí hay algunas soluciones:
Descompostura:
declare
imprime cada variable definida (exportada o no) y función.declare -f
imprime solo funciones.comm -3
eliminará todas las líneas comunes a ambos. En efecto, esto eliminará las funciones, dejando solo las variables.Para imprimir solo variables que no se exportan:
Otra solución alternativa:
Esto solo imprimirá las variables, pero con algunos atributos feos.
Puede cortar los atributos usando ... cortar:
Una desventaja es que el valor de IFS se interpreta en lugar de mostrarse.
comparar:
Esto hace que sea bastante difícil usar esa salida para un procesamiento posterior, debido a que está solo
"
en una línea. Quizás se pueda hacer algo de IFS-fu para evitar esto.Otra solución alternativa, usando
compgen
:El bash builtin
compgen
estaba destinado a ser utilizado en scripts de finalización. Para este fin,compgen -v
enumera todas las variables definidas. La desventaja: enumera solo los nombres de las variables, no los valores.Aquí hay un truco para enumerar también los valores.
La ventaja: es una solución pura de bash. La desventaja: algunos valores están en mal estado debido a la interpretación a través de
printf
. Además, la subshell de la tubería y / o el bucle agrega algunas variables adicionales.fuente
declare ...| cut
rompe su tubería si no hay atributos para una variable? Supongo que--
se usa en ese caso, pero todavía estoy incómodo.sed
podría ser más seguro, es decirdeclare -p | sed 's/^.* \([^ ]\+\)$/\1/'
compgen
:)El
typeset
incorporado tiene extrañamente una opción para mostrar solo funciones (-f
) pero no solo para mostrar parámetros. Afortunadamente,typeset
(oset
) muestra todos los parámetros antes de que todas las funciones, funciones y nombres de parámetros no puedan contener líneas nuevas o signos iguales, y las líneas nuevas en los valores de los parámetros se citan (aparecen como\n
). Entonces puede detenerse en la primera línea que no contiene un signo igual:Esto solo imprime los nombres de los parámetros; si desea los valores, cambie
print $1
aprint $0
.Tenga en cuenta que esto imprime todos los nombres de parámetros (los parámetros y las variables se usan como sinónimos aquí), no solo las variables de entorno ("variable de entorno" es sinónimo de "parámetros exportados").
Tenga en cuenta también que esto supone que no hay una variable de entorno con un nombre que no coincida con las restricciones de bash en los nombres de los parámetros. Dichas variables no se pueden crear dentro de bash, pero se pueden heredar del entorno cuando se inicia bash:
fuente
set | sed '/=/!Q'
No estoy seguro de cómo se pueden hacer
set
variables de solo impresión. Sin embargo, al observar la salida deset
, pude llegar a lo siguiente que parece tomar solo variables:Básicamente, estoy buscando líneas que comiencen con letras, números o signos de puntuación seguidos de un "=". De la salida que vi, esto toma todas las variables; Sin embargo, dudo que esto sea muy portátil.
Si, como sugiere su título, desea restar de esta lista las variables que se exportan y, por lo tanto, obtener una lista de variables no exportadas, entonces podría hacer algo como esto
Para desglosar esto un poco, esto es lo que hace:
set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" | sort > ./setvars
: Con suerte, obtiene todas las variables (como se discutió antes), las ordena y pega el resultado en un archivo.&& env | sort
: Después de completar el comando anterior, vamos a llamarenv
y ordenar su salida.| comm -23 ./setvars -
: Por último, canalizar la salida ordenada deenv
dentrocomm
y utilizar la-23
opción de imprimir las líneas que son únicos para el primer argumento, en este caso las líneas únicas para nuestra salida del conjunto.Cuando haya terminado, es posible que desee limpiar el archivo temporal que creó con el comando
rm ./setvars
fuente
f () {|cat <<EOF|foo=bar|EOF|}
donde|
representa un salto de línea).Solo usa el comando
env
. No imprime funciones.fuente
Prueba el comando printenv:
fuente
En bash, esto imprimirá solo nombres de variables:
O, si también se necesitan valores, use:
fuente
diferenciarse contra un shell limpio para garantizar que también se omitan los vars de los scripts rc
la versión con
comm
sería demasiado complicadafuente
La respuesta aceptada es genial. Estoy ofreciendo una alternativa que no implica configurar el modo POSIX:
Aquí está la técnica que he estado usando para almacenar el estado de la función en un archivo para poder continuar más tarde. El primero produce un volcado de estado y el segundo produce solo una lista de los nombres de las variables.
Ambos funcionan volcando líneas hasta encontrar uno sin un carácter '=', que ocurre cuando se enumera la primera función. Este último recorta la tarea.
fuente