/ / zsh: sostituzione del comando, quoting corretto e backslash (di nuovo) - zsh

zsh: sostituzione di comandi, quoting corretto e backslash (di nuovo) - zsh

(Nota: questa è una domanda successiva al mio intervento zsh: sostituzione di comandi e quotazione corretta , ma ora con una complicazione aggiuntiva).

Ho una funzione _iwpath_helper, che emetteper stdout di un percorso, che eventualmente contiene spazi. Per il gusto di questa discussione, supponiamo che _iwpath_helper restituisca sempre un testo costante, ad esempio

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

Ho anche una funzione che quote_stripped si aspettaparametro e se questo parametro è circondato da virgolette, le rimuove e restituisce il testo rimanente. Se il parametro non è circondato da virgolette, lo restituisce invariato. Ecco la sua definizione:

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

Ora combino entrambe le funzioni nel modo seguente:

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

(Naturalmente, "quote_stripped" non sarebbe necessario in questo esempio di giocattolo, perché _iwpath_helper non restituisce un percorso delimitato da virgolette qui, ma nella vera applicazione, a volte lo fa).

Il problema ora è che la variabile target contiene a vero carattere backslash, cioè se faccio a

echo +++$target+++

Vedo

+++home/rovf/my directory with spaces

e se provo a

cd $target

Ottengo sul mio sistema il messaggio di errore, che la directory

home/rovf/my/ directory/ with/ spaces

non esisterebbe

(Nel caso ti stia chiedendo dove l'avantile barre provengono da: sto funzionando su Cygwin, e suppongo che il comando cd interpreti i backslash come barre in avanti in questo caso, per adattarsi meglio all'ambiente Windows).

Immagino i backslash, che appaiono fisicamente nella variabile bersaglio sono causati dalla (q) bandiera di espansione che ioapplica a $ (_ iwpath_helper). Il mio problema ora è che non posso semplicemente rilasciare il (q), perché senza di esso, la funzione quote_stripped otterrebbe sul parametro $ 1 solo la prima parte della stringa, fino al primo spazio (/ Home / rovf / mia).

Come posso scrivere correttamente?

risposte:

1 per risposta № 1

Penso che tu voglia solo evitare di provare a togliere le virgolette manualmente, e usare il (Q) bandiera di espansione. Confrontare:

% 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 per risposta № 2

chepner aveva ragione: il modo in cui ho cercato di rimuovere la stringa era sciocco (stavo pensando troppo a un "Bourne Shell way"), e avrei dovuto usare la (Q) flag.

Ecco la mia soluzione:

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

Non c'è più bisogno della funzione quote_stripped ....