Come posso eseguire lo script locale sul computer remoto e includere argomenti?


116

Ho scritto uno script che funziona bene quando eseguito localmente:

./sysMole -time Aug 18 18

Gli argomenti "-time" , "Aug" , "18" e "18" vengono passati correttamente allo script.

Ora, questo script è progettato per essere eseguito su un computer remoto ma, da una directory locale sul computer locale. Esempio:

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole

Anche questo funziona bene. Ma il problema sorge quando provo ad includere questi argomenti sopra menzionati (-time 18 agosto 18) , ad esempio:

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole -time Aug 18 18

Dopo aver eseguito quello script ottengo il seguente errore:

bash: cannot set terminal process group (-1): Invalid argument
bash: no job control in this shell

Per favore, dimmi cosa sto facendo di sbagliato, questo è molto frustrante.


1
"Bash -s" è uno dei modi in cui è possibile eseguire uno script dall'input standard (cioè un file).
AllenD

Risposte:


160

Eri abbastanza vicino con il tuo esempio. Funziona bene quando lo usi con argomenti come questi.

Script di esempio:

$ more ex.bash 
#!/bin/bash

echo $1 $2

Esempio che funziona:

$ ssh serverA "bash -s" < ./ex.bash "hi" "bye"
hi bye

Ma non riesce per questi tipi di argomenti:

$ ssh serverA "bash -s" < ./ex.bash "--time" "bye"
bash: --: invalid option
...

Cosa sta succedendo?

Il problema che stai riscontrando è che l'argomento, -timeo --timenel mio esempio, viene interpretato come un passaggio a bash -s. È possibile pacificare bashinterrompendolo dal prendere uno qualsiasi degli argomenti rimanenti della riga di comando per sé usando l' --argomento.

Come questo:

$ ssh root@remoteServer "bash -s" -- < /var/www/html/ops1/sysMole -time Aug 18 18

Esempi

# 1:

$ ssh serverA "bash -s" -- < ./ex.bash "-time" "bye"
-time bye

# 2:

$ ssh serverA "bash -s" -- < ./ex.bash "--time" "bye"
--time bye

# 3:

$ ssh serverA "bash -s" -- < ./ex.bash --time "bye"
--time bye

# 4:

$ ssh  < ./ex.bash serverA "bash -s -- --time bye"
--time bye

NOTA: Solo per chiarire che ovunque il reindirizzamento appare sulla riga di comando non fa alcuna differenza, perché sshchiama comunque una shell remota con la concatenazione dei suoi argomenti, la quotazione non fa molta differenza, tranne quando è necessario quotare sulla shell remota come nell'esempio n. 4:

$ ssh  < ./ex.bash serverA "bash -s -- '<--time bye>' '<end>'"
<--time bye> <end>

4
sei un genio! Cosa devo fare per raggiungere il tuo livello? Ho un sacco di lavoro tagliato. Grazie mille.
AllenD

14
@AllenD - continua a porre domande e prova a partecipare sul sito il più possibile. Cerco sempre di imparare qualcosa di nuovo ogni giorno. Prima della tua domanda non sapevo nemmeno come fare. 8-). Grazie per la tua domanda!
slm

5
si noti che il reindirizzamento può apparire in qualsiasi punto del comando: ad esempio bash -s -- --time bye < ./ex.basho anche < ./ex.bash bash -s -- --time bye. questo perché la shell prima estrae l'istruzione di reindirizzamento (indipendentemente da dove si trova nel comando), quindi imposta il reindirizzamento, quindi esegue il resto della riga di comando con il reindirizzamento in atto.
lesmana,

@sim Sto provando a fare esattamente la stessa cosa, ma dall'interno di uno script, non dalla riga di comando. Qualche idea su come farlo? Per qualche motivo, racchiudere la risposta esatta nei backtick non funziona affatto. Esegue invece lo script specificato localmente e l'output viene inviato come comando a bash su ssh
krb686

@ krb686 - Lo chiederei come nuovo Q.
slm

5

Sulla gestione degli argomenti arbitrari

Se stai davvero usando solo una singola stringa, ad es. -time Aug 18 18, puoi semplicemente codificarlo e le risposte esistenti ti diranno come farlo in modo adeguato. D'altra parte, se è necessario passare argomenti sconosciuti (come un messaggio da visualizzare sull'altro sistema o il nome di un file creato in cui gli utenti finali potrebbero controllarne il nome), è necessario prestare maggiore attenzione.


Con basho kshcome/bin/sh

Se il tuo telecomando /bin/shè fornito da bash o ksh, puoi tranquillamente eseguire le seguenti operazioni con un elenco di argomenti non attendibile, in modo tale che anche nomi dannosi (come $(rm -rf $HOME).txt) possano essere passati come argomenti in modo sicuro:

runRemote() {
  local args script

  script=$1; shift

  # generate eval-safe quoted version of current argument list
  printf -v args '%q ' "$@"

  # pass that through on the command line to bash -s
  # note that $args is parsed remotely by /bin/sh, not by bash!
  ssh user@remote-addr "bash -s -- $args" < "$script"
}

Con qualsiasi conforme POSIX /bin/sh

Per essere al sicuro da dati di argomento sufficientemente dannosi (tentando di trarre vantaggio dalla quotazione non POSIX conforme utilizzata da printf %qin bash quando sono presenti caratteri non stampabili nella stringa in escape) anche con un /bin/shvalore POSIX di base (come dasho ash), esso diventa un po 'più interessante:

runRemote() {
  local script=$1; shift
  local args
  printf -v args '%q ' "$@"
  ssh user@remote-addr "bash -s" <<EOF

  # pass quoted arguments through for parsing by remote bash
  set -- $args

  # substitute literal script text into heredoc
  $(< "$script")

EOF
}

Utilizzo (per uno dei precedenti)

Le funzioni sopra indicate possono quindi essere invocate come:

# if your time should be three arguments
runRemote /var/www/html/ops1/sysMole -time Aug 18 18

...o...

# if your time should be one string
runRemote /var/www/html/ops1/sysMole -time "Aug 18 18"

-3

dire che aa è un file locale che contiene ls

$ssh servername "cat | bash" < a.a

cambia 127.0.0.1 a qualunque sia il tuo IP remoto

questi due danno un messaggio sull'allocazione pseudo tty ma funzionano.

$ cat a.a | ssh 127.0.0.1

$ ssh 127.0.0.1 <a.a

O

$ cat a.a | ssh 127.0.0.1 bash or

$ ssh 127.0.0.1 bash < a.a


2
Faccio fatica a vedere fino a che punto questo risponde alla domanda.
ChrisWue,

La qualità e la formattazione sono dubbie. Non vedo nessuna nuova informazione utile che non sia presente nella risposta accettata.
Julie Pelletier,

@JuliePelletier Ho fornito alcuni esempi di "gatti" non presenti nella risposta accettata. È bene conoscere modi alternativi di fare le cose.
barlop

Non è una buona cosa; i tuoi gatti sono inutili.
Scott,

2
Oh mio Dio. Ho lasciato fuori il collegamento all'uso inutile del gatto perché pensavo che ormai tutti avessero sentito parlare della frase; a quanto pare è stata una cattiva ipotesi da parte mia.
Scott,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.