Jak wydrukować „$” w dokumencie tutaj

42

Jak mogę powtórzyć „$” w dokumencie doc w bash?

Na przykład chcę mieć plik z zawartością na zdalnym serwerze, takim jak $ABC=home_dir.

$ ssh hostname sudo -s <<EOF
echo "$ABC=home_dir" > file
EOF

Ale byłoby to traktowane jako zmienna. Jak mogę wydrukować literał $?

użytkownik21485
źródło
2
możesz użyć pojedynczych cytatów
Rahul Patil
2
To jest dużo pośrednich zachowań. Czy na pewno nie możesz utworzyć pliku na lokalnym hoście, a następnie scpgo?
l0b0

Odpowiedzi:

65

Jeśli chcesz napisać dokument tutaj i nie chcesz, aby ŻADNY z dokumentów został rozwinięty lub zinterpretowany przez znaki specjalne, możesz zacytować etykietę pojedynczymi cudzysłowami:

$ cat >file <<'EOF'
echo "$ABC=home_dir"
EOF

Jednak twoja sytuacja opisana w twoim przykładzie jest znacznie bardziej złożona, ponieważ tak naprawdę wysyłasz tę zawartość za pośrednictwem ssh do zdalnego systemu, który ma być uruchamiany przez sudo, które również wywołuje powłokę (i aby powłoka rozwijała zawartość także). Będziesz potrzebował więcej poziomów cytowania, aby to zrobić poprawnie, ale mimo to nadal nie będzie działać, ponieważ sudo wymaga terminala (aby mógł poprosić o hasło), a ty przekierowałeś ze standardowego wejścia. Nawet używanie ssh -tnie pomoże tutaj.

Zgadzam się również z Johanem. Nie jest jasne, czy naprawdę tego chcesz; zwróć uwagę, że przypisywanie wartości do odwołania do zmiennej powłoki jest nielegalne, więc jeśli ten plik, który próbujesz utworzyć, ma być skryptem powłoki, nie będzie działał tak, jak go opisałeś. Być może, jeśli wykonasz kopię zapasową i opisasz, co naprawdę chcesz zrobić, możemy Ci pomóc.

Szalony naukowiec
źródło
To najlepsza odpowiedź, ponieważ może obsłużyć bardzo długie TUTAJ dokumenty. Jest (głównie) odporny na idioty.
Felipe Alvarez
22

Escape the $

$ ssh hostname sudo -s <<EOF
echo "\$ABC=home_dir" > file
EOF

Nie wiem, jaki jest twój przypadek użycia, ale zwykle chcesz home_dir=$ABCzamiast $ABC=home_dir.

lesmana
źródło
2
To rozwiązanie zadziała, ale czy naprawdę tego chce OP? Wydaje się, że generuje skrypt powłoki, który po uruchomieniu zapisze w „pliku” ciąg znaków, który odrzuci ABC dla lewej strony przypisania i prawdopodobnie skończy się =home_dirw pliku? Oczywiście nie wiem, jaki jest przypadek użycia ...
Johan
2
Spowoduje to, że literał $zostanie wysłany do zdalnej powłoki, ale wtedy ta powłoka rozszerzy się, $ABCzanim wyświetli ciąg znaków file. Aby zapisać literał $w pliku, będziesz potrzebować kolejnego (ukośnego) ukośnika odwrotnego:, echo "\\\$ABC=home_dir"aby otrzymać zdalną powłokę echo "\$ABC=home_dir".
chepner
9

Najtańszym sposobem ucieczki byłby

$ ssh hostname sudo -s << \EOF
echo "$ABC=home_dir" > file
EOF
Bernhard
źródło
4

Zapisujesz sobie poziom cytowania, wysyłając ciąg do catprocesu na zdalnym końcu:

echo 'echo $ABC=home_dir' | ssh hostname sudo -s "cat > file"

Pojedyncze cudzysłowy chronią $lokalny koniec, a łańcuch nigdy nie jest widziany przez powłokę z drugiej strony, ponieważ jest odczytywany bezpośrednio przez cat(via sudo), zamiast być argumentem dla innego polecenia powłoki.

Twój kod wymaga dodatkowej warstwy ucieczki, aby chronić $:

$ ssh hostname sudo -s <<EOF
echo "\\\$ABC=home_dir" > file
EOF

Musisz wysłać literał \$do zdalnego hosta, aby zdalna powłoka zapisała literał $do pliku. Możesz to również uprościć, cytując znacznik tutaj:

$ ssh hostname sudo -s <<\EOF
echo "\$ABC=home_dir" > file
EOF
chepner
źródło