Caracteres de escape de shell para sh -c

Necesito ejecutar un command con argumento (s) escapado (s) usando sh -c. Sé que la cadena parece bastante fea, pero las simples no causan problemas.

La salida del eco cuando se pasa a sh -c es diferente que cuando se ejecuta solo y estoy luchando para encontrar la manera de solucionarlo.

Antecedentes: [1] Estoy escapando de los arguments al command echo porque esto se transfirió y quería asegurarme de que no se insertan commands adicionales. [2] Estoy usando sh -c porque quería tener la capacidad de usar instalaciones de shell como | o nohup, etc. [3] Probablemente no sea relevante, pero esto se está ejecutando a través de una connection ssh a un server remoto.

El command y la salida del command sh -c es:

sh -c "echo \a\\\\\b\;\c" ;c 

El command y la salida del command autónomo es:

 echo \a\\\\\b\;\c a\\b;c 

¡Cualquier ayuda sería muy apreciada!

\ se usa para escaping de algunos caracteres (como \ itself, " , $ , ` ) y eliminar caracteres de nueva línea dentro de comillas dobles, por lo que

 sh -c "echo \a\\\\\b\;\c" 

es como

 sh -c 'echo \a\\\b\;\c' 

Para ese sh, \ se usa para escaping de cada personaje, por lo que se convierte en lo mismo que

 echo 'a\b;c' 

Los echo conformes a UNIX se expanden \b en un carácter de retroceso ( ^H ) que, cuando se envía a un terminal, mueve el cursor hacia atrás un carácter hacia la izquierda, por lo que el ; sobrescribe la a , que es la razón por la que ves ;c .

echo es un command no portátil cuyo comportamiento varía mucho de shell a shell y sistema a sistema. Lo mejor es evitarlo especialmente si se le presentan arguments que pueden contener barras diagonales inversas o pueden comenzar con un guion. Use printf en su lugar.

 sh -c 'printf "%s\n" "a\\\\b;c"' 

para dar salida a\\b;c .

(3 barras invertidas hubieran sido suficientes, pero es más seguro recordar que dentro de las comillas dobles, se necesitan dos barras diagonales inversas para get una).

Para implementaciones de echo que expanden secuencias de escape como las tuyas, deberías duplicar el número de barras diagonales inversas.

 sh -c 'echo "a\\\\\\\\b;c"' 

Si quiere evitar las comillas dobles, solo necesitará escaping de ; carácter que es el único especial para el shell (además de \ que ya ha escapado en la versión de comillas dobles).

 sh -c 'echo a\\\\\\\\b\;c' 

Si desea utilizar comillas dobles en lugar de comillas simples, nuevamente tendrá que duplicar el número de barras diagonales inversas.

 sh -c "echo a\\\\\\\\\\\\\\\\b\\;c" 

Y si quiere deshacerse de las comillas, necesita escaping del espacio y ; de nuevo para el caparazón exterior.

 sh -c echo\ a\\\\\\\\\\\\\\\\b\\\;c