To pytanie nie dotyczy tego, jak napisać poprawnie literał łańcucha znaków. Nie mogłem znaleźć żadnego powiązanego pytania, które nie dotyczyłoby ucieczki przed zmiennymi w celu bezpośredniego wykorzystania w skrypcie lub przez inne programy.
Moim celem jest umożliwienie skryptowi generowania innych skryptów. Wynika to z faktu, że zadania w wygenerowanych skryptach będą uruchamiane w dowolnym miejscu od 0 do n razy na innym komputerze, a dane, z których zostały wygenerowane, mogą ulec zmianie przed ich uruchomieniem (ponownie), więc wykonywanie operacji bezpośrednio, przez sieć nie działa.
Biorąc pod uwagę znaną zmienną, która może zawierać znaki specjalne, takie jak pojedyncze cudzysłowy, muszę ją zapisać jako dosłowny ciąg znaków, np. Zmienna foo
zawierająca bar'baz
powinna pojawić się w wygenerowanym skrypcie jako:
qux='bar'\''baz'
który zostałby napisany przez dodanie "qux=$foo_esc"
do innych wierszy skryptu. Zrobiłem to przy użyciu Perla w następujący sposób:
foo_esc="'`perl -pe 's/('\'')/\\1\\\\\\1\\1/g' <<<"$foo"`'"
ale wydaje się, że to przesada.
Nie odniosłem sukcesu, robiąc to sam z bash. Próbowałem wielu odmian tych:
foo_esc="'${file//\'/\'\\\'\'}'"
foo_esc="'${file//\'/'\\''}'"
ale albo dodatkowe ukośniki pojawiają się na wyjściu (kiedy to robię echo "$foo"
), albo powodują błąd składniowy (oczekując dalszych danych wejściowych, jeśli zrobione z powłoki).
alias
i / lubset
dość ogólniealias "varname=$varname" varname
lubvar=value set
Odpowiedzi:
Bash ma opcję rozszerzenia parametrów dla dokładnie tego przypadku :
Więc w tym przypadku:
Jest to obsługiwane w wersji Bash 4.4 i nowszych. Istnieje kilka opcji dla innych form rozwijania, a także dla generowania kompletnych instrukcji przypisania (
@A
).źródło
bad substitution
."${foo:q}"
."${foo@Q}"
Pracuje!Bash zawiera
printf
wbudowany%q
specyfikator formatu, który wykonuje dla ciebie ucieczkę powłoki, nawet w starszych (<4.0) wersjach Bash:Tej sztuczki można także użyć do zwrócenia tablic danych z funkcji:
Zauważ, że
printf
wbudowane Bash różni się odprintf
narzędzia, które jest dostarczane w pakiecie z większością systemów operacyjnych typu Unix. Jeśli z jakiegoś powoduprintf
polecenie wywołuje narzędzie zamiast wbudowanego, zawsze można wykonaćbuiltin printf
zamiast tego.źródło
'Ne'\''er do well'
itd., Tj. Cytaty zawarte w wydruku.[[ 'Ne'\''er do well' == Ne\'er\ do\ well ]] && echo 'equivalent!'
equivalent!
'hello'
skutkuje niepoprawną wartością''\''hello''
, która zawiera niepotrzebne początkowe puste ciągi (pierwsze dwa pojedyncze cudzysłowy) i niewłaściwy końcowy pojedynczy cytat.$'escape-these-chars'
to funkcja cytowania ANSI-C w Bash, która powoduje, że wszystkie znaki w określonym ciągu są ucieczkowe. Tak więc, aby łatwo utworzyć literał łańcuchowy, który zawiera nowy wiersz w nazwie pliku (np.$'first-line\nsecond-line')
Użyj\n
w tej konstrukcji.Chyba nie RTFM. Można to zrobić w następujący sposób:
Następnie
echo "$foo_esc"
podaje oczekiwane'bar'\''baz'
Tak naprawdę używam go z funkcją:
Modyfikowanie tego w celu użycia
printf
wbudowanego rozwiązania Dejay:źródło
Istnieje kilka rozwiązań, aby podać wartość var:
alias
W większości powłok (gdzie alias jest dostępny) (z wyjątkiem csh, tcsh i prawdopodobnie innych csh jak):
Tak, działa to w wielu
sh
podobnych powłokach, takich jak kreska lub popiół.set
Także w większości powłok (znowu nie csh):
skład
niektórych powłokach (przynajmniej ksh, bash i zsh):
eksport
Najpierw wykonaj:
Następnie użyj:
ksh
export -p | grep 'qux='
bashexport -p | grep 'qux='
zsh
export -p qux
quote
bash
echo "${qux@Q}"
zsh
echo "${(qq)qux}"
# od jednego do czterech q może być użyte.źródło
grep
zexport
lubset
może pęknąć na zmiennych zawierających wbudowane znaki nowej linii.