/ / zsh: podstawianie poleceń, poprawne cytowanie i ukośnik odwrotny (ponownie) - zsh

zsh: podstawianie poleceń, poprawne cytowanie i ukośnik odwrotny (ponownie) - zsh

(Uwaga: jest to następstwo pytania do mojego ogłoszenia zsh: Podstawianie poleceń i poprawne cytowanie , ale teraz z dodatkowym utrudnieniem).

Mam funkcję _iwpath_helper, która wyprowadzastdout ścieżkę, która może zawierać spacje. Na potrzeby tej dyskusji załóżmy, że na przykład _iwpath_helper zawsze zwraca stały tekst

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

Mam również funkcję quote_stripped spodziewa się jednegoParametr i jeśli ten parametr jest otoczony cudzysłowami, usuwa je i zwraca pozostały tekst. Jeśli parametr nie jest otoczony cudzysłowami, zwraca go bez zmian. Oto jego definicja:

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

Teraz łączę obie funkcje w następujący sposób:

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

(Oczywiście "quote_stripped" byłoby niepotrzebne w tym zabawkowym przykładzie, ponieważ _iwpath_helper nie zwraca tu ścieżki z ograniczeniem cytowania, ale w prawdziwej aplikacji czasami to robi).

Problem polega na tym, że zmienna target zawiera real ukośnik odwrotny, tj. jeśli zrobię

echo +++$target+++

Widzę

+++home/rovf/my directory with spaces

i jeśli spróbuję

cd $target

Dostaję się do mojego systemu komunikat o błędzie, że katalog

home/rovf/my/ directory/ with/ spaces

nie istnieje.

(W przypadku, gdy zastanawiasz się, gdzie do przoduPochodzą z ukrycia: używam Cygwin i domyślam się, że polecenie cd po prostu interpretuje ukośniki odwrotne jako ukośniki w tym przypadku, aby lepiej pasowały do ​​środowiska Windows).

Myślę, że backslashes, które fizycznie pojawiają się w zmiennej cel są powodowane przez (q) flagę ekspansji, którą jazastosuj do $ (_ iwpath_helper). Mój problem polega na tym, że nie mogę po prostu upuścić (q), ponieważ bez niego funkcja quote_stripped otrzymywałaby parametr $ 1 tylko pierwszą część ciągu, aż do pierwszej przestrzeni (/ home / rovf / my).

Jak mogę to poprawnie napisać?

Odpowiedzi:

1 dla odpowiedzi № 1

Myślę, że chcesz po prostu uniknąć ręcznego usuwania wycinków i korzystania z (Q) flaga rozszerzenia. Porównać:

% 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 dla odpowiedzi nr 2

chepner miał rację: sposób, w jaki próbowałem anulować ciąg, był głupi (zbyt dużo myślałem w "Bourne Shell way") i powinienem używać flagi (Q).

Oto moje rozwiązanie:

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

Nie ma już potrzeby funkcji quote_stripped ....