Problema al escaping arguments parametrizados

Me siento muy reacio a hacer esta pregunta, ya que parece que me falta algo realmente obvio. Sin embargo, no puedo encontrar las preguntas existentes con exactamente el mismo problema.

Tenemos un script que no deberíamos editar, y está causando un problema en cómo maneja arguments que incluyen espacios en blanco. Reduje el problema a un caso reproducible muy simple:

Primero, creé una secuencia de commands simple que simplemente genera los arguments de la línea de command pasados ​​a ella:

#!/bin/bash for i; do echo $i done 

Luego defino una variable de entorno que se pasará a la command-line

 MYOPT="With Space" 

Entonces, y esta es la parte que no puedo cambiar en nuestro entorno, llamo al command usando la variable como parámetro. Lamentablemente, la variable no se cita en nuestro entorno.

 ./mycommand.sh $MYOPT 

El resultado de esto es, como era de esperar,

 ./mycommand.sh $MYOPT "With Space" 

Si cites la variable en el command anterior, funciona. Esta parece ser la solución generalmente aceptada para este problema al analizar otras preguntas similares.

 ./mycommand.sh "$MYOPT" "With Space" 

Sin embargo, como mencioné, no podemos cambiar cómo se llama este script.

Traté de agregar presupuestos extra en la variable de entorno de la siguiente manera, pero esto tampoco ayudó:

 MYOPT="\"With Space\"" ./mycommand.sh $MYOPT "With Space" 

¿Hay alguna manera de definir esta variable de entorno con espacios tales que se pueda pasar a un script sin citarlo en la invocación?

Para aquellos que están interesados, este problema se presenta en nuestro entorno RHEL7 tomcat. JAVA_OPTS se establece en tomcat.conf y tenemos -Dpatwigters = "con espacios". El script de control principal que viene con Tomcat no cita estos JAVA_OPTS cuando llama a Java, lo que lleva a este problema. Reduje el problema al simple ejemplo anterior.

No puede volver de ./mycommand.sh $MYOPT al valor de MYOPT . Es por eso que no encontraste una manera de hacerlo: es imposible. mycommand.sh no recibe suficiente información para rebuild el valor original.

Por ejemplo, si el valor de MYOPT es * entonces se llama a mycommand.sh con la list de nombres de file en el directory actual. No tiene forma de saber cómo se construyó esta list.

Si sabes que el valor de MYOPT sigue ciertas reglas, entonces puedes rebuildlo. La versión simple de estas reglas es:

  • El valor no contiene ninguno de los caracteres \[*? o pestaña o nueva línea.
  • El valor no comienza o termina con un espacio y no contiene espacios consecutivos.

Bajo estas suposiciones, "$*" en mycommand.sh le dará el valor de MYOPT . Pero tenga en count que esto no puede funcionar en general.

La solución adecuada es arreglar tu entorno. En el lenguaje de shell, $MYOPT no significa "tomar el valor de MYOPT ", significa "tomar el valor de MYOPT , dividirlo de acuerdo con el valor de IFS , y tratar cada parte resultante como un patrón de comodín que se expande si coincide con al less un file ". La forma de escribir "tomar el valor de MYOPT " es "$MYOPT" , o más generalmente usar $MYOPT dentro de comillas dobles .