Aunque export
no funciona muy bien con $(shell ...)
, hay una solución simple. Podemos pasar los datos al script de shell a través de la línea de comando.
Ahora, por supuesto, el paso medio ambiente es robusto frente a los problemas de escape y citando. Sin embargo, el lenguaje de shell tiene un único método de cotización de cotización '...'
que maneja todo. El único problema es que no hay forma de obtener una sola cotización allí; pero por supuesto que se resuelve mediante la terminación de la cita, la barra invertida-escape de la comilla simple necesaria y comenzar una nueva cita: En otras palabras:
ab'cd -> 'ab'\''cd'
En el script ejecutado por $(shell ...)
que acabamos de generar una asignación variable de la formulario var='$(...)'
, donde $(...)
es alguna expresión de expresión que interpola material escapado de forma adecuada. Por lo tanto, Makefile
:
somevar := apple with 'quoted' "stuff" and dollar $$signs
shell_escape = $(subst ','\'',$(1))
update := $(shell v='$(call shell_escape,$(somevar))'; echo $$v > file.txt)
.phony: all
all:
cat file.txt
de ejecución de la muestra:
$ make
cat file.txt
apple with 'quoted' "stuff" and dollar $signs
Si queremos comunicar una variable de entorno a un comando, podemos hacer que el uso de la sintaxis del shell VAR0=val0 VAR1=val1 ... VARn=valn command arg ...
. Esto se puede ilustrar con algunas alteraciones menores de lo anterior Makefile
:
somevar := apple with 'quoted' "stuff" and dollar $$signs
shell_escape = $(subst ','\'',$(1))
update := $(shell somevar='$(call shell_escape,$(somevar))' env > file.txt)
.phony: all
all:
grep somevar file.txt
Run:
$ make
grep somevar file.txt
somevar=apple with 'quoted' "stuff" and dollar $signs
file.txt
contiene un volcado de variables de entorno, en el que podemos ver somevar
. Si export
en GNU Make hicieron lo correcto, hubiéramos podido acaba de hacer:
export somevar
update := $(shell env > file.txt)
pero el resultado final es el mismo.
Dado que el resultado final que desea es echo $(update)
, podría shell_escape
de todos modos, incluso si pasa GNU exportado vars a $(shell ...)
.Es decir, mirar a una más Makefile
:
somevar := apple with 'quoted' "stuff" and dollar $$signs
shell_escape = $(subst ','\'',$(1))
update := $(shell v='$(call shell_escape,$(somevar))'; echo $$v)
.phony: all
all:
@echo '$(call shell_escape,$(update))'
@echo $(update)
Salida:
apple with 'quoted' "stuff" and dollar $signs
apple with quoted stuff and dollar
De hecho, es bug [http://savannah.gnu.org/bugs/?10593] que no está fijado y tal vez nunca lo será. Gracias, intentaré no molestarte con preguntas extrañas sobre los archivos make. – Pablo
@Michael: de mi lectura del manual de GNUMake no es un error. (Y usted no tiene que poner @Beta delante de un comentario a mi respuesta.) – Beta
Esto no es raro. Necesito este. ¿Por qué necesito esto? Porque el entorno es la única forma a prueba de balas de pasar una cadena arbitraria a un script externo. Por ejemplo, supongamos que tengo una variable V que contiene cosas: citas de varios tipos, metacaracteres de shell significativos como dólares, escapes de barra invertida, etc. Me gustaría que un script de shell usara la variable $ V. – Kaz