Per la risposta di zanco , non stai fornendo un comando remoto a ssh, dato come la shell analizza la riga di comando. Per risolvere questo problema, modificare la sintassi sshdell'invocazione del comando in modo che il comando remoto sia composto da una stringa multilinea sintatticamente corretta.
Esistono varie sintassi che possono essere utilizzate. Ad esempio, poiché i comandi possono essere reindirizzati bashe sh, e probabilmente anche altre shell, la soluzione più semplice è semplicemente combinare l' sshinvocazione della shell con heredocs:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Si noti che l'esecuzione di quanto sopra senza /bin/bash comporterà l'avviso Pseudo-terminal will not be allocated because stdin is not a terminal. Nota inoltre che EOTè racchiuso tra virgolette singole, in modo da bashriconoscere l'eredoc come un nowdoc , disattivando l'interpolazione della variabile locale in modo che il testo del comando venga passato così com'è ssh.
Se sei un fan delle pipe, puoi riscrivere quanto sopra come segue:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Lo stesso avvertimento /bin/bashvale per quanto sopra.
Un altro approccio valido è passare il comando remoto multilinea come una singola stringa, usando più livelli di bashinterpolazione variabile come segue:
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
La soluzione sopra risolve questo problema nel modo seguente:
ssh user@serverviene analizzato da bash e viene interpretato come il sshcomando, seguito da un argomento user@serverda passare al sshcomando
"inizia una stringa interpolata, che una volta completata comprenderà un argomento da passare al sshcomando, che in questo caso verrà interpretato sshcome il comando remoto da eseguire comeuser@server
$( inizia un comando da eseguire, con l'output catturato dalla stringa interpolata circostante
catè un comando per generare il contenuto di qualunque file segue. L'output di catverrà passato nuovamente nella stringa interpolata di acquisizione
<<inizia un branco ereditario
'EOT'specifica che il nome dell'eredità è EOT. Le singole virgolette che 'circondano EOT specificano che l'ereditarietà dovrebbe essere analizzata come nowdoc , che è una forma speciale di ereditarietà in cui i contenuti non vengono interpolati da bash, ma piuttosto trasmessi in formato letterale
Qualsiasi contenuto riscontrato tra <<'EOT'e <newline>EOT<newline>verrà aggiunto all'output nowdoc
EOTtermina nowdoc, creando un file temporaneo nowdoc che viene restituito al catcomando chiamante . catgenera l'outdoc e restituisce l'output alla stringa interpolata di acquisizione
) conclude il comando da eseguire
"conclude la stringa interpolata di acquisizione. Il contenuto della stringa interpolata verrà restituito sshcome singolo argomento della riga di comando, che sshinterpreterà come il comando remoto da eseguire comeuser@server
Se devi evitare di usare strumenti esterni come cat, e non ti dispiace avere due istruzioni invece di una, usa il readbuilt-in con un heredoc per generare il comando 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…