Soluzione
Unendo insieme molte informazioni provenienti da diverse fonti, ecco cosa mi è venuto in mente.
Demone locale
Dal computer locale (OSX), configura un demone per l'ascolto su una porta specifica, tramite launchd
(vedi i link sotto). Il processo demone chiamerà semplicemente pbcopy
, che prenderà qualsiasi cosa passato attraverso STDIN
e lo metterà negli appunti. Per fare questo è necessario impostare un file plist launchd
. Il mio sembrava così:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.pbcopy.9999</string>
<key>UserName</key>
<string>joe</string>
<key>Program</key>
<string>/usr/bin/pbcopy</string>
<key>StandardOutPath</key>
<string>/tmp/pb9999.out</string>
<key>StandardErrorPath</key>
<string>/tmp/pb9999.err</string>
<key>Sockets</key>
<dict>
<key>Listeners</key>
<dict>
<key>SockNodeName</key>
<string>localhost</string>
<key>SockServiceName</key>
<string>9999</string>
</dict>
</dict>
<key>inetdCompatibility</key>
<dict>
<key>Wait</key>
<false/>
</dict>
</dict>
</plist>
Per convenzione, il nome del file plist dovrebbe essere il nome dell'etichetta con .plist
aggiunto, quindi per l'esempio precedente, sarebbe local.pbcopy.9999.plist
. Se si desidera utilizzare una porta diversa da 9999, è sufficiente cambiarla ovunque (tenendo presente che dovrebbe essere superiore a 1024 e non dovrebbe essere una porta nota che potrebbe già essere utilizzata). Una volta che hai funzionato, puoi rimuovere StandardOutPath
e StandardErrorPath
di chiavi e stringhe, poiché sono necessarie solo per il debug.
Per caricare il demone, eseguire il seguente comando:
$ launchctl load local.pbcopy.9999.plist
Puoi vedere che è stato caricato o rimosso con i seguenti comandi:
$ launchctl list local.pbcopy.9999
$ launchctl remove local.pbcopy.9999
Se desideri che questo venga caricato ogni volta che accedi, posiziona il file plist nella directory ~/Library/LaunchAgents
.
Nota: dovrai impostarlo su ciascun host locale su cui desideri che questo funzioni.
SSH Port-Forwarding
Poiché potrei accedere al computer remoto da diversi computer locali, non riesco a codificare l'invio dei dati sul computer remoto su un host specifico. Per rendere questo il più indolore e dinamico possibile, ho utilizzato il port forwarding SSH per creare un collegamento dinamico dalla macchina remota al computer locale (il come e il perchè di questo sono oltre questa risposta, vedi sotto per maggiori informazioni) . Nello specifico, creo un collegamento dalla porta 9997 delle macchine remote alla porta 9999 del computer locale, che ora ha un daemon in ascolto su di esso, grazie alla roba launchd
sopra. Potrei usare la porta 9999 sia sulla macchina remota che sul computer locale, ma non è necessario.
Per configurare questo tunnel, eseguire il seguente comando:
$ ssh -R 9997:localhost:9999 [email protected]
È possibile eseguire il controllo remoto in più macchine remote con lo stesso comando e tutte funzioneranno come previsto. Puoi remotare nello stesso computer remoto più volte con lo stesso comando, e funzionerà come previsto; vedi nota sotto.
Se non hai voglia di digitare -R 9997:localhost:9999
su ogni chiamata SSH effettuata, puoi inserire la definizione di inoltro remoto nel file di configurazione SSH per farlo automaticamente. Ecco un esempio dal mio file ~/.ssh/config
:
Host ufo*
RemoteForward 9997 localhost:9999
Con ciò, ogni volta che I SSH ad un host il cui nome inizia con 'ufo', l'inoltro remoto da 9997 a localhost: 9999 verrà automaticamente impostato. Vedi il link alla pagina man del file di configurazione di seguito per ulteriori opzioni.
Invio di dati
Sul lato remoto uso netcat
per inviare il contenuto desiderato al demone di ascolto.
$ date | nc localhost 9997
Puoi diventare complicato quanto vorresti:
$ nc localhost 9997 <<EOF
> 'ls -ld *'
> 'date'
> EOF
Puoi persino decidere in modo dinamico se inviare o meno dati, in base al fatto che qualcuno stia ascoltando o meno (probabilmente c'è un modo più efficiente per farlo, ma funziona):
#!/bin/bash
cnt='(netstat -lnptu 2>/dev/null) | grep 127.0.0.1:9999 | grep -v grep | wc -l'
if [[ $cnt -eq 1 ]]; then
date | nc localhost 9999
fi
Osservazioni e amp; Avvertimenti
Cose che ho notato:
-
pbcopy
funziona bene con Copy'em Paste
- se si avvia più di una sessione SSH con la stessa porta remota che inoltra alla stessa macchina remota, solo la prima avrà alcun effetto; nessun errore di tipo "porta duplicata" verrà riportato su entrambi i lati
- allo stesso modo, se esegui il remote-out da diversi computer locali alla stessa macchina remota utilizzando la stessa porta remota (ad esempio 9997), solo il primo avrà un effetto
Link di riferimento