Cosa fa `<& -`?


20

Ho copiato uno snippet di Bash in background un comando ssh eseguito in remoto:

ssh user@remote <<CMD
some process <&- >log 2>error &
CMD

Cosa fa <&-?
La mia ipotesi è che sia lo stesso di< /dev/null

Il mio prossimo comprensione è che i tre principali descrittori di file ( stdin, stdout, stderr) devono essere chiusi per impedire:

  1. Il lavoro in background e la sceneggiatura in uscita - in qualche modo in conflitto?
  2. Quando il terminale si chiude, tutti i processi che accettano lo stdin dal terminale vengono chiusi?

Riferimenti incrociati obbligatori: vedere quali sono gli operatori di controllo e reindirizzamento della shell? - anche se tutto ciò che dice di questo operatore è che "può essere usato per chiudere o duplicare i descrittori di file" e dovresti "vedere la sezione pertinente del manuale della tua shell".
G-Man dice 'Reinstate Monica' il

Se ricordo bene, ssh -nNT user@remote 'command'creerò una sessione SSH non interattiva. Aggiungi &in background, anteponi nohupa commandper mantenerlo in esecuzione se la connessione si interrompe.
Mark K Cowan,

1
@MarkKCowan man sshsuggerisce che -N disabilita completamente l'esecuzione di un comando remoto e un test rapido lo supporta.
Tom Hunt,

Ah sì, ho usato -nNTR per il port forwarding inverso. Ignora quindi -N e -R :)
Mark K Cowan,

Risposte:


30

<&-non è esattamente la stessa cosa di < /dev/null. <&-chiude fd 0, mentre lo < /dev/nullreindirizza dal dispositivo /dev/null, che non fornisce mai alcun dato e fornisce sempre EOF in lettura. La differenza è principalmente che una read(2)chiamata da un FD chiuso (il <&-caso) genererà un errore con EBADF, mentre una chiamata da un FD reindirizzato null non restituirà nessun byte letto (condizione di fine file). Se il tuo programma non legge mai da stdin, la distinzione non ha importanza.

Chiudere gli FD è una buona pratica se si esegue il background di qualcosa, poiché un processo in background si bloccherà se si tenta di leggere qualcosa da TTY. Questo esempio, tuttavia, non gestisce completamente tutto ciò che dovrebbe; idealmente ci sarebbe una nohupo setsidinvocazione da qualche parte, per dissociare completamente il processo in background.


Quindi dovrei usare nohupoltre alla chiusura dei descrittori di file?
Eric Francis,

2
Il metodo più completo (che imita il modo in cui i programmi si demonizzano da soli) è qualcosa di simile setsid some process <&- >path/to/log 2>path/to/error. Il metodo più veloce è qualcosa di simile nohup some process &.
Tom Hunt,

2
@EricFrancis: l'uso nohupnon ha senso qui. nohupimpedire al processo di ricevere il HUPsegnale quando il suo terminale di controllo è chiuso. Ma in questo caso non avevi alcun terminale.
cuonglm,

@TomHunt: il processo in background non si è bloccato, lo ha fatto la sessione ssh.
cuonglm,

2
non è una buona idea chiudere fds 0, 1 e 2 ... non vuoi che il prossimo fd creato prenda uno di quei valori. meglio reindirizzarli a / dev / null
Murray Jensen,

7

Vedi man bash:

  [n]<&word

viene utilizzato per duplicare i descrittori di file di input. Se si wordespande a una o più cifre, il descrittore di file indicato da nviene creato come copia di quel descrittore di file. Se le cifre in word non specificano un descrittore di file aperto per l'input, si verifica un errore di reindirizzamento. Se la parola restituisce -, il descrittore di file nviene chiuso. Se nnon specificato, viene utilizzato l'input standard (descrittore di file 0).


La definizione corretta è che non è specificato cosa succede quando hai [n]<&worde la parola contiene più di una singola cifra.
schily,

Cosa intendi? È man bashsbagliato?
Eric Francis,

@EricFrancis perché non specificato nello standard, bashsceglie di implementarlo in modo sano (per una definizione adeguata di "sano"). Altre shell possono o meno farlo.
Muru,

@muru La domanda è taggata bash, no posix-shell.
Barmar,

@Barmar ok. Così...?
muru,

7

<&- chiudi input standard.

Il modulo generale, definito da POSIX , è:

[n]<&word

Il suo scopo di creare un descrittore di file nè una copia del descrittore di file indicato da word. Lo standard in è assunto se nomesso e, in caso wordaffermativo -, il descrittore di file nverrà chiuso.

Non è lo stesso di </dev/null, da quando in caso di </dev/null, l'input standard è stato ancora aperto ed è stato reindirizzato in un altro posto.

È necessario chiudere tutti i descrittori di file dei processi collegati al socket ssh, altrimenti la sessione ssh non può chiudersi.

È possibile eseguire il comando sul computer remoto senza collegarlo alla sessione ssh, usando screen o tmux :

ssh user@remote 'screen -S test -d -m command'

Perché il voto negativo?
cuonglm,
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.