Tengo una aplicación que toma como entrada los atributos en comillas dobles incrustadas en comillas simples. Tome por ejemplo este comando correcto:
command -p 'cluster="cl1"'
Para automatizarlo, creé un archivo bash usando $CLUSTER
como variable. ¿Cómo debe ser mi comando? En otras palabras, ¿qué debo poner en lugar de cl1?
Tenga en cuenta que, si modifiqué el comando anterior, no será aceptado. Por ejemplo: command -p "cluster=cl1"
no se acepta
CLUSTER='"cl1"'; command -p "cluster=$CLUSTER"
cli
sin comillas dentro de laCLUSTER
variable):CLUSTER='cl1'; command -p 'cluster="'"$CLUSTER"'"'
Respuestas:
Parece que su comando está configurando variables de entorno basadas en argumentos dados en la línea de comandos. Puede ser que puedas hacer:
... y establecer su entorno para ello en la invocación.
De lo contrario, las citas de shell suelen delimitar argumentos o escapar de otros caracteres especiales de shell de la interpretación de shell. Puede contener (y por lo tanto escapar) diferentes tipos de comillas de shell dentro de otros tipos basados en varias reglas:
"''''"
- una cadena entre comillas puede contener cualquier cantidad de comillas."\""
- una\
barra invertida puede escapar de una"
comilla dentro de una"
cadena entre comillas.\\
también se escapa una barra diagonal inversa, el\$
token de expansión y las\n
líneas de contacto como se indica a continuación, pero por lo demás se trata literalmente."${expand} and then some"
- una cadena entre comillas puede contener una$
expansión de shell interpretada .'"\'
- una'
cadena entre comillas puede contener cualquier carácter que no sea una'
comilla.\
- una barra invertida sin comillas escapará a cualquier carácter siguiente para una interpretación literal, incluso otra barra invertida, excepto una línea\n
electrónica.\\n
caso ewline, tanto la\
barra diagonal inversa como la línea\n
ew se eliminan por completo del comando interpretado resultante.${parameter+expand "$parameter"}
- las comillas resultantes de una expansión de shell casi nunca sirven como marcadores delimitadores, excepto algunos casos especiales. No me aventuraré a describirlos más aquí.Considero extraño que cualquier aplicación interprete comillas en sus argumentos de línea de comandos. Tal práctica no tiene mucho sentido en que, al menos para los shells, el propósito principal de una cita es generalmente delimitar un argumento. Sin embargo, en la invocación, los argumentos siempre están delimitados con
\0NUL
caracteres y, por lo tanto, una cita no puede servir de mucho.Incluso un shell normalmente solo se molestará en interpretar citas en uno de sus argumentos de invocación cuando se lo llama con un
-c
interruptor, lo que denota que su primer operando es en realidad un script de shell que debe ejecutarse al invocarlo. Este es un caso de entrada dos veces evaluada .Dicho todo esto, puede hacer varias cosas para pasar comillas literales a través de argumentos en la línea de comandos. Por ejemplo:
Como señalé en un comentario antes, puede contener las
"
comillas dentro de una expansión que se"
cita.Puede escapar
"
con una\
barra diagonal inversa dentro de la"
cadena entre comillas.Puede alternar y concatenar estilos de citas para llegar al resultado final deseado como @jimmij observa arriba .
Puede deshabilitar tanto la generación como la
$IFS
división de nombres de archivo , evitando así la necesidad de citar el$expansion
, y así solo citar las citas. Esto es probablemente exagerado.Por último, hay otro tipo de shell-quote que podría usarse. Como señalé antes, la
sh -c "$scriptlet"
forma de invocación de shell a menudo se usa para proporcionar un script de shell en la línea de comandos. Sin$scriptlet
embargo, cuando se complica, como cuando las comillas deben contener otras comillas, a menudo puede ser ventajoso usar un documento aquí y en sush -s
lugar, donde el shell tiene instrucciones específicas de asignar todos los operandos siguientes a los parámetros posicionales como lo haría en un-c
caso y sin embargo también tomar su guión destdin
.Si su comando debe interpretar las comillas de esta manera, lo consideraría mejor si pudiera hacerlo en una entrada de archivo. Por ejemplo:
Si no cita el delimitador de a,
<<here-document
entonces todos sus contenidos se tratan casi exactamente como si fueran"
comillas blandas, excepto que"
las comillas dobles no se tratan especialmente. Y así, si ejecutamos lo anterior con en sucat
lugar:... imprime ...
fuente
Como escribió mikeserv :
"Cita doble" cada literal que contiene espacios / metacaracteres y cada expansión:
"$var"
,"$(command "$var")"
,"${array[@]}"
,"a & b"
. Utilizar'single quotes'
para el código o literal$'s: 'Costs $5 US'
,ssh host 'echo "$HOSTNAME"'
. Verhttp://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments
http://wiki.bash-hackers.org/syntax/words
fuente
"
caracteres; solo el primero y el último deberían ser suficientes. El verdadero problema aquí es su aplicación interpretando citas en un argumento. Interpretar una cita en un argumento casi nunca es una buena idea porque una cita solo debe ser un medio para delimitar un argumento, y en la invocación esa delimitación es manejada por\0NUL
s en todos los casos. ¿Probablemente hay una mejor manera de pasar la información que desea a la aplicación? ¿Como acommand --'script=/path/to/some/file'
o algo?