/ / zsh: sustitución de comando, comillas correctas y barra diagonal inversa (otra vez) - zsh

zsh: sustitución de comando, comillas correctas y barra diagonal inversa (otra vez) - zsh

(Nota: esta es una pregunta sucesora a mi publicación zsh: sustitución de comando y cita apropiada , pero ahora con una complicación adicional).

Tengo una función _iwpath_helper, que producepara establecer un camino, que posiblemente contiene espacios. Por el bien de esta discusión, asumamos que _iwpath_helper siempre devuelve un texto constante, por ejemplo

function _iwpath_helper
{
echo "home/rovf/my directory with spaces"
}

También tengo una función quote_stripped espera unaparámetro y si este parámetro está rodeado por comillas, los elimina y devuelve el texto restante. Si el parámetro no está rodeado por comillas, lo devuelve sin cambios. Aquí está su definición:

function quote_stripped
{
echo ${1//[""]/}
}

Ahora combino ambas funciones de la siguiente manera:

target=$(quote_stripped "${(q)$(_iwpath_helper)}")

(Por supuesto, "quote_stripped" no sería necesario en este ejemplo de juguete, porque _iwpath_helper no devuelve una ruta delimitada por comillas aquí, pero en la aplicación real, a veces sí).

El problema ahora es que el objetivo variable contiene un real carácter de barra inclinada invertida, es decir, si hago un

echo +++$target+++

Ya veo

+++home/rovf/my directory with spaces

y si trato de

cd $target

Entro en mi sistema el mensaje de error, que el directorio

home/rovf/my/ directory/ with/ spaces

no existiría

(En caso de que se esté preguntando hacia dóndeLas barras vienen de: estoy corriendo en Cygwin, y supongo que el comando cd simplemente interpreta barras diagonales inversas como barras diagonales en este caso, para acomodarse mejor para el entorno de Windows).

Supongo que las barras invertidas, que aparecen físicamente en la variable objetivo son causados ​​por la bandera de expansión (q) queaplicar a $ (_ iwpath_helper). Mi problema ahora es que no puedo simplemente descartar el (q), porque sin él, la función quote_stripped obtendría el parámetro $ 1 solo la primera parte de la cadena, hasta el primer espacio (/ home / rovf / my)

¿Cómo puedo escribir esto correctamente?

Respuestas

1 para la respuesta № 1

Creo que solo quieres evitar intentar quitar presupuestos manualmente, y usar (Q) bandera de expansión Comparar:

% v="a b c d"
% echo "$v"
a b c d
% echo "${(q)v}"
a b c d
% echo "${(Q)${(q)v}}"
a b c d

0 para la respuesta № 2

chepner tenía razón: la manera en que traté de unir la cuerda era tonto (estaba pensando demasiado en una "forma de Bourne Shell"), y debería haber usado la bandera (Q).

Aquí está mi solución:

target="${(Q)$(_iwpath_helper)}"

Ya no se necesita la función quote_stripped ....