Zgodnie z odpowiedzią zanco nie udostępniasz polecenia zdalnego ssh
, biorąc pod uwagę sposób, w jaki powłoka analizuje wiersz poleceń. Aby rozwiązać ten problem, zmień składnię ssh
wywołania polecenia, tak aby zdalne polecenie składało się z poprawnego pod względem składni, ciągu zawierającego wiele wierszy.
Istnieje wiele różnych składni, których można użyć. Na przykład, ponieważ polecenia mogą być rurami do bash
i sh
i prawdopodobnie inne powłoki zbyt najprostszym rozwiązaniem jest po prostu połączyć ssh
powłoki wywołania z heredocs:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Zauważ, że wykonanie powyższego bez /bin/bash
spowoduje ostrzeżenie Pseudo-terminal will not be allocated because stdin is not a terminal
. Zauważ też, że EOT
jest otoczony pojedynczymi cudzysłowami, dzięki czemu bash
rozpoznaje heredoc jako nowdoc , wyłączając lokalną interpolację zmiennych, aby tekst polecenia był przekazywany „tak jak jest”ssh
.
Jeśli jesteś fanem rur, możesz przepisać powyższe w następujący sposób:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
To samo zastrzeżenie /bin/bash
dotyczy powyższego.
Innym ważnym podejściem jest przekazanie wieloliniowego zdalnego polecenia jako pojedynczego łańcucha, przy użyciu wielu warstw bash
interpolacji zmiennych w następujący sposób:
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
Powyższe rozwiązanie rozwiązuje ten problem w następujący sposób:
ssh user@server
jest analizowany przez bash i jest interpretowany jako ssh
polecenie, a następnie argument user@server
przekazywany do ssh
polecenia
"
rozpoczyna interpolowany ciąg, który po zakończeniu będzie zawierać argument, który zostanie przekazany do ssh
polecenia, które w tym przypadku będzie interpretowane ssh
jako zdalne polecenie do wykonania jakouser@server
$(
rozpoczyna polecenie do wykonania, a wyjście jest przechwytywane przez otaczający interpolowany ciąg
cat
to polecenie do wyświetlania zawartości dowolnego pliku, który następuje. Dane wyjściowe cat
zostaną przekazane z powrotem do przechwyconego interpolowanego ciągu
<<
zaczyna bash heredoc
'EOT'
określa, że nazwa heredoc to EOT. Pojedyncze cytaty '
otaczające EOT określają, że heredok powinien być analizowany jako nowdoc , co jest specjalną formą heredoc, w której zawartość nie jest interpolowana przez bash, ale raczej przekazywana w formacie dosłownym
Każda treść napotkana między <<'EOT'
i <newline>EOT<newline>
zostanie dołączona do danych wyjściowych nowdoc
EOT
kończy nowdoc, co powoduje utworzenie pliku tymczasowego nowdoc i przekazanie go z powrotem do cat
komendy wywołującej . cat
wysyła nowdoc i przekazuje dane wyjściowe do przechwyconego interpolowanego ciągu
)
kończy polecenie do wykonania
"
kończy przechwycony interpolowany ciąg. Zawartość interpolowanego ciągu zostanie przekazana z powrotem ssh
jako pojedynczy argument wiersza poleceń, który ssh
będzie interpretowany jako polecenie zdalne do wykonania jakouser@server
Jeśli chcesz uniknąć korzystania z zewnętrznych narzędzi, takich jak cat
i nie masz nic przeciwko posiadaniu dwóch instrukcji zamiast jednej, użyj read
wbudowanego narzędzia heredoc do wygenerowania polecenia SSH:
IFS='' read -r -d '' SSH_COMMAND <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
ssh user@server "${SSH_COMMAND}"
ssh user@server /bin/bash <<EOT…