Canali standard
In informatica i canali standard (o standard streams), in tutti i moderni sistemi operativi, rappresentano i dispositivi logici di input e di output che collegano un programma con l'ambiente operativo in cui esso viene eseguito (tipicamente un terminale testuale) e che sono connessi automaticamente al suo avvio.
Questi canali predefiniti sono disponibili nei sistemi operativi Unix e Unix-like, negli ambienti d'esecuzione del linguaggio C e C++ e nei loro derivativi.
I tre canali di input/output predefiniti sono detti standard input, standard output e standard error (talvolta abbreviati rispettivamente in stdin, stdout e stderr).
Storia
[modifica | modifica wikitesto]Nella maggior parte dei sistemi operativi antecedenti Unix, i programmi dovevano creare in maniera esplicita i collegamenti ai dati di input e di output. Per molti di tali sistemi ciò poteva costituire una vera e propria sfida di abilità di programmazione, per via della complessità dei dettagli tecnici necessari per ottenere ad esempio la configurazione dell'ambiente di esecuzione, o per accedere ad una tabella di file locali, o per determinare l'insieme di dati su cui operare e per gestire distintamente i casi specifici per schede e nastri perforati, nastri magnetici, dischi, stampanti e terminali interattivi.
Unix fu fonte di innovazioni radicali, inclusa l'astrazione delle periferiche di input/output: ciò liberò i programmi dall'onere di dover conoscere o gestire il tipo di periferiche con cui stavano comunicando. I sistemi operativi predecessori obbligavano il programmatore ad effettuare operazioni di lettura e scrittura in blocchi di dati, spesso con semantiche dei dati e del controllo delle periferiche che non erano ortogonali. Unix eliminò tale complessità introducendo il concetto di flusso di dati, ovvero sequenze ordinate di byte che potevano essere lette fino al loro esaurimento. Un programma aveva inoltre la possibilità di effettuare scritture di quantità arbitrarie di dati, senza dover dichiarare in anticipo le dimensioni totali ed il modo in cui raggrupparli.
Un'altra innovazione di Unix fu quella di mettere a disposizione automaticamente dei canali di input e di output predefiniti: nel tipico caso di un programma che acquisisce dati in input e li elabora per poi produrre i risultati in output, il programma (ed il programmatore) non ha bisogno di fare alcunché per preparare i canali di input e di output; i sistemi operativi predecessori di Unix, al contrario, richiedevano solitamente di preparare delle istruzioni—spesso complesse—espresse in Job Control Language, o comunque demandavano al programma un onere equivalente.
Dato che Unix forniva i canali standard, gli ambienti d'esecuzione del linguaggio C dovettero offrire supporto in tal senso, col risultato che oggi gran parte di essi (e dei discendenti del linguaggio C) forniscono funzionalità equivalenti indipendentemente dal sistema operativo.
Descrizione
[modifica | modifica wikitesto]Standard input (stdin)
[modifica | modifica wikitesto]Lo standard input è un canale da cui giunge un flusso di dati (spesso testuali) in ingresso ad un programma. Il programma li trasferisce effettuando operazioni di lettura. Non tutti i programmi necessitano di dati in input: ad esempio i comandi ls o dir (che mostrano il contenuto delle directory) svolgono il loro compito senza bisogno di leggere dati in input.
Il flusso di input, salvo casi di redirezione, proviene dal terminale (es. dall'utente tramite tastiera) da cui il programma è stato avviato.
Il descrittore di file associato allo standard input è quello con indice 0; la variabile del linguaggio C corrispondente, definita in <stdio.h>, è FILE* stdin; analogamente, la variabile del linguaggio C++ definita in <iostream> è std::cin.
Standard output (stdout)
[modifica | modifica wikitesto]Lo standard output è il canale su cui un programma scrive i suoi dati in output. Il programma trasferisce i dati effettuando operazioni di scrittura. Non tutti i programmi producono output: ad esempio il comando mv (che cambia il nome di un file o di una directory) normalmente non produce dati in output.
Il flusso di output, salvo casi di redirezione, è diretto al terminale da cui il programma è stato avviato (es. a monitor o console a favore dell'utente).
Il descrittore di file associato allo standard output è quello con indice 1; la variabile del linguaggio C corrispondente, definita in <stdio.h>, è FILE* stdout; analogamente, la variabile del linguaggio C++, definita in <iostream>, è std::cout.
Standard error (stderr)
[modifica | modifica wikitesto]Lo standard error è un altro canale di output, tipicamente usato dai programmi per i messaggi d'errore o di diagnostica. Esso è un canale indipendente dallo standard output, e se ne può effettuare la redirezione separatamente dagli altri. La sua destinazione è solitamente il terminale da cui il programma è stato avviato, in modo da rendere massime le possibilità di essere visto anche quando lo standard output è diretto altrove: ad esempio, nel caso di una pipeline software, l'output di un programma è fornito come input al programma successivo, ma i suoi messaggi d'errore sono ancora visualizzati sul terminale.
È accettabile e normale che lo standard output e lo standard error abbiano la stessa destinazione, come nel caso del terminale testuale: i messaggi compaiono nello stesso ordine in cui il programma li scrive, salvo quando sono in uso dei buffer (ad esempio quando lo standard error non ha buffer e lo standard output ha un buffer di linea: in questo caso i dati scritti sullo standard error in un secondo momento possono apparire prima dei dati scritti su standard output in un primo momento, in quanto il buffer dello standard output potrebbe non essere ancora stato riempito).
Il descrittore di file associato allo standard error è quello con indice 2; la variabile del linguaggio C corrispondente, definita in <stdio.h>, è FILE* stderr; nel linguaggio C++ <iostream> definisce due variabili associate a questo canale: std::cerr e std::clog, delle quali la prima non ha buffer mentre la seconda usa buffer analoghi agli altri canali del C++.
La maggior parte delle shell testuali permettono di effettuare la redirezione dello standard output e dello standard error verso lo stesso file con la sintassi
>& nome_file
equivalente di:
&> nome_file
La Bourne shell ed i suoi derivativi permettono di indirizzare lo standard error alla stessa destinazione dello standard output con la sintassi
2> &1
Cronologia
[modifica | modifica wikitesto]Anni 1950: Fortran
[modifica | modifica wikitesto]Fortran fornì l'equivalente dei descrittori di file Unix, UNIT=5
per lo standard input e UNIT=6
per lo standard output.
! FORTRAN 77 example PROGRAM MAIN READ(UNIT=5,*)NUMBER WRITE(UNIT=6,'(F5.3)')' NUMBER IS: ',NUMBER END
1960: ALGOL 60
[modifica | modifica wikitesto]ALGOL 60 fu criticato poiché non forniva un meccanismo standard d'accesso ai file.
1968: ALGOL 68
[modifica | modifica wikitesto]Con il termine transput si faceva complessivamente riferimento alle funzionalità di input e di output dell'ALGOL 68. Koster coordinò la definizione dello standard transput. Tale standard includeva: stand in
, stand out
, stand error
e stand back
.
Esempio:
# ALGOL 68 example # main:( REAL number; getf(stand in,($g$,number)); printf(($"Number is: "g(6,4)"OR "$,number)); # OR # putf(stand out,($" Number is: "g(6,4)"!"$,number)); newline(stand out) )
Input: | Output: |
---|---|
3.14159 | Number is: +3.142 OR Number is: +3.142! |
Anni 1970: C e Unix
[modifica | modifica wikitesto]Nel linguaggio C i canali stdin
, stdout
e stderr
furono associati rispettivamente ai descrittori di file Unix 0, 1 e 2.
Anni 1980: C++
[modifica | modifica wikitesto]Nel C++ i canali standard furono associati rispettivamente agli oggetti cin
, cout
e cerr
.
Anni 1990: Java
[modifica | modifica wikitesto]In Java e nei linguaggi aderenti a tale piattaforma i canali standard sono riferiti a: System.in
(per stdin), System.out
(per stdout), e System.err
(per stderr). A titolo d'esempio si può usare l'oggetto BufferedReader della classe BufferedReader
:
public static void main(String args[]) { try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String s = br.readLine(); double number = Double.parseDouble(s); System.out.println("Number is:" + number); } catch (Exception e) { System.err.println("Error:" + e.getMessage()); } }
Oppure è possibile usare la classe Scanner
, appartenente al package java.util
public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNextLine()) { String line = sc.nextLine(); double number = Double.parseDouble(line); System.out.println("Number is: " + number); } }
Anni 2000: .NET
[modifica | modifica wikitesto]Nel C sharp ed altri linguaggi del .NET Framework i canali standard divennero accessibili via System.Console
(per lo standard input e lo standard output) e System.Console.Error
(per lo standard error)
// C# example public static int Main() { double number; string s; try { s = System.Console.ReadLine(); number = double.Parse(s); System.Console.WriteLine("Number is: {0:F3}", number); return 0; } catch (System.FormatException e) { // if Parse() threw an exception System.Console.Error.WriteLine("No number was entered!"); return 1; } }
' Visual Basic .NET example Public Function Main() As Integer Dim number As Double Dim s As String Try s = System.Console.ReadLine() number = CDbl(s) System.Console.WriteLine("Number is: {0:F3}", number) Return 0 Catch e As System.InvalidCastException ' if Parse() threw an exception System.Console.Error.WriteLine("No number was entered!") Return 1 End Try End Function
GUI
[modifica | modifica wikitesto]Le interfacce grafiche fanno raramente uso dei canali standard, e di conseguenza con esse la redirezione e le pipeline software non sono né pratiche né utili. Le azioni di taglia, copia e incolla tra applicazioni diverse sono probabilmente ciò che meglio approssima il concetto dei canali standard, ma visto che esse vanno effettuate manualmente, il doverne effettuare un gran numero non risulta essere particolarmente efficiente. Un'eccezione a quanto detto può essere Dynamic window manager, che legge dallo standard input messaggi di stato da visualizzare.
Alcuni programmi con interfaccia grafica, prevalentemente nei sistemi Unix e Unix-like, usano tuttora lo standard error per scrivere i loro messaggi diagnostici.
Bibliografia
[modifica | modifica wikitesto]- KRONOS 2.1 Reference Manual, Control Data Corporation, Part Number 60407000, 1974
- NOS Version 1 Applications Programmer's Instant, Control Data Corporation, Part Number 60436000, 1978
- Level 68 Introduction to Programming on MULTICS Archiviato il 25 febbraio 2021 in Internet Archive., Honeywell Corporation, 1981
- Evolution of the MVS Operating System, IBM Corporation, 1981
- Lions' Commentary on UNIX Sixth Edition, John Lions, ISBN 1-57398-013-7, 1977
- Console Class, .NET Framework Class Library, Microsoft Corporation, 2008
Voci correlate
[modifica | modifica wikitesto]Collegamenti esterni
[modifica | modifica wikitesto]- (EN) Denis Howe, standard input/output, in Free On-line Dictionary of Computing. Disponibile con licenza GFDL
- (EN) Standard Output Definition - by The Linux Information Project (LINFO)