2013-12-10 16 views
13

Sto creando un piccolo set di script per l'avvio, l'arresto e il controllo in remoto dello stato di un processo. Lo stop di questi script dovrebbe cercare un processo e ucciderlo. Perciò faccio:Come sfuggire al carattere di virgoletta singola in un comando ssh/remote bash?

ssh [email protected] 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '{print $2}' | head -n 1`' 

Il problema qui è che il passo awk tokenizzazione ha bisogno di virgolette singole e questi si scontrano con la sola offerta utilizzato per l'esecuzione del comando remoto tramite ssh. Come possono essere sfuggite queste singole virgolette?

+0

Prova> ssh implementare @ hera 'kill -9 \ 'ps -ef | grep MapReduceNode | grep -v "grep" | awk -F "" "'" {print $ 2} "'" | head -n 1 \ '' – RedX

+0

@RedX Funziona grazie! usalo come risposta e accetterò. –

risposta

18

Uso

ssh [email protected] 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '"'"'{print $2}'"'"' | head -n 1`' 
8

Questo non ssh o awk è gestire le citazioni, è il guscio (e sono necessarie per mantenere il guscio dalla manipolazione altri caratteri speciali, come $). Nesting non è supportato (anche se altre strutture, come ad esempio $() possono nidificare anche se contengono virgolette), quindi è necessario sfuggire le singole virgolette separatamente. Ecco un paio di metodi:

$ echo 'Don'"'"'t mess with this apostrophe!' 
Don't mess with this apostrophe! 
$ echo 'Don'\''t mess with this apostrophe!' 
Don't mess with this apostrophe! 
7

Non è possibile includere una virgoletta singola in una stringa con quotatura singola. Tuttavia, questo non importa, perché un singolo argomento può avere più di un segmento citato

Per esempio (a patto che non v'è spazio bianco non quotate o altri caratteri auto-delimita.):

ssh [email protected] 'kill -9 `ps -ef | 
       grep MapReduceNode | 
       grep -v "grep" | 
       awk -F " " '\''{print $2}'\'" | 
       head -n 1`" 

Tuttavia , quella riga di comando è molto goffo. Se possibile, è necessario utilizzare l'utilità pkill, che ridurrebbe tutto a ssh [email protected] 'pkill -SIGKILL MapReduceNode'.

Altrimenti si potrebbe fare tutta la manipolazione di stringhe in un unico awk invocazione (non testato, ma penso che funzionerà):

ssh [email protected] 'ps -ef | 
       awk "/[M]apReduceNode/{system(\"kill -9 \"$2)}"' 

(a differenza dell'originale, questo ucciderà tutti i compiti MapReduceNode piuttosto che un arbitrario primo. Se vuoi veramente fare in un'unica operazione, aggiungi ; exit all'azione awk.)

1

Ci sono altre due opzioni che non vedo menzionate in nessuna delle altre risposte. Ho lasciato il grep/grep/awk/gasdotto testa intatta a scopo dimostrativo, anche se (come accennato in rici's answer) potrebbe essere ridotto a qualcosa di simile

awk -F ' ' '/MapReduceNod[e]/ {print $2; exit}' 
  1. Usando doppi apici per tutta la comando ssh:

    ssh [email protected] "kill -9 \$(ps -ef | 
    grep MapReduceNode | grep -v \"grep\" | awk -F ' ' '{print \$2}' | head -n 1)" 
    

    noti che posso usare apici nel comando ora, ma devo scappare altre cose non voglio ancora ampliato: \$() (che ho usato invece di apici inversi), doppio cita \" e print \$2.

  2. Un here-doc con delimitatore citato:

    ssh -T [email protected] <<'EOF' 
    kill -9 $(ps -ef | grep MapReduceNode | grep -v 'grep' | 
    awk -F ' ' '{print $2}' | head -n 1) 
    EOF 
    

    Il -T impedisce ssh lamentano non assegnare uno pseudo-terminale.

    Il qui-doc con delimitatore citato è bello in più perché i suoi contenuti non devono essere modificati a tutti con rispetto le cose in fuga, e può contenere virgolette singole.

0

Un altro esempio è quello di affrontare con le virgolette semplici o doppie, perché per me per esempio avevo bisogno interpretazione e sostituzioni variabili. Se voglio fare una funzione per visualizzare un msg al MacOS della mia donna che posso fare seguenti:

ssh womanLptp "osascript -e 'tell app \"System Events\" to display dialog \"${1}\"'" 
Problemi correlati