GNU/Linux >> Linux Esercitazione >  >> Linux

È possibile che il descrittore di file linux 0 1 2 non sia per stdin, stdout e stderr?

A livello di descrittore di file, stdin è definito come descrittore di file 0 , stdout è definito come descrittore di file 1; e stderr è definito come descrittore di file 2 . Guarda questo.

Anche se il tuo programma, o la shell, cambia (ad es. reindirizzamento con dup2(2)) qual è il descrittore di file 0, rimane sempre stdin (poiché per definizione STDIN_FILENO è 0).

Chiamate di sistema come open(2) o pipe(2) o socket(2) possono dare ad es. STDIN_FILENO (cioè 0) se quel descrittore di file è libero (ad esempio perché è stato close(2)-d prima). Ma quando ciò accade, è ancora stdin per definizione.

Naturalmente, in stdio(3), il FILE stream stdin è un po' più complesso. Il tuo programma potrebbe fclose(3), freopen(3), fdopen(3) ...


Sebbene esistessero già un paio di risposte, non le ho trovate abbastanza informative da spiegare la storia completa.

Dato che sono andato avanti e ho fatto ulteriori ricerche, aggiungo le mie scoperte.

Ogni volta che un processo viene avviato, una voce del processo in esecuzione viene aggiunta a /proc/<pid> directory. Questo è il luogo in cui vengono conservati tutti i dati relativi al processo. Inoltre, all'avvio del processo, il kernel alloca 3 descrittori di file al processo per la comunicazione con i 3 flussi di dati indicati come stdin , stdout e stderr .
il kernel Linux utilizza un algoritmo per creare sempre un FD con il valore intero più basso possibile in modo che questi flussi di dati siano mappati sui numeri 0 , 1 e 2 .

Poiché questi non sono altro che riferimenti a un flusso e possiamo chiudere un flusso. Si può facilmente chiamare close(<fd>) , nel nostro caso close(1) , per chiudere il descrittore di file.

facendo ls -l /proc/<pid>/fd/ , vediamo solo 2 FD elencati lì 0 e 2 .
Se ora eseguiamo un open() chiamare il kernel creerà un nuovo FD per mappare questo nuovo riferimento al file e poiché il kernel usa l'algoritmo del primo numero intero più basso, prenderà il valore intero 1 .

Quindi ora, il nuovo FD creato punta al file che abbiamo aperto (usando il open() chiamata di sistema)
Qualsiasi trasferimento di dati che avviene ora non avviene tramite il flusso di dati predefinito precedentemente collegato, ma il nuovo file che abbiamo aperto.

Quindi sì, possiamo mappare l'FD 0 , 1 o 2 a qualsiasi file e non è necessario stdin , stdout o stderr


Linux
  1. È possibile rendere l'output di stdout e stderr di colori diversi in XTerm o Konsole?

  2. Sotto Linux, è possibile crittografare una cartella/partizione in modo che non sia accessibile a nessuno senza la password?

  3. È possibile salvare il contenuto della console virtuale Linux e scorrere all'indietro in un file?

  4. bash:reindirizza stderr al file e stdout + stderr allo schermo

  5. Acquisizione di STDERR e STDOUT da archiviare utilizzando tee

Risolto il problema con Grub che non veniva visualizzato per il sistema di avvio doppio di Windows e Linux

50 Comando grep produttivo e pratico per gli appassionati di Linux

20 migliori software di crittografia di dischi e file per desktop Linux

Confuso su stdin, stdout e stderr?

Come cercare un file nei file war,ear e jar in modo ricorsivo in Linux

Cosa rende una distribuzione GNU e ci sono distribuzioni Linux che non sono GNU?