Successivo: Funzioni di tempo, Precedente: Funzioni per stringhe, Su: Funzioni predefinite [Contenuti][Indice]
Le seguenti funzioni riguardano l’input/output (I/O). I parametri opzionali sono racchiusi tra parentesi quadre ([ ]):
close(
nome_file [,
come])
Chiude il file nome_file in input o in output. Alternativamente, l’argomento può essere un comando della shell usato per creare un coprocesso, o per ridirigere verso o da una pipe; questo coprocesso o pipe viene chiuso. Vedi la sezione Chiudere ridirezioni in input e in output per ulteriori informazioni.
Quando si chiude un coprocesso, può talora essere utile chiudere dapprima
un lato della pipe bidirezionale e quindi chiudere l’altro.
Questo si può fare fornendo un secondo argomento a close()
.
Questo secondo argomento (come)
dovrebbe essere una delle due stringhe "to"
o "from"
,
che indicano quale lato della pipe chiudere. La stringa può essere
scritta indifferentemente in maiuscolo o in minuscolo.
Vedi la sezione Comunicazioni bidirezionali con un altro processo,
che tratta questa funzionalità con maggior dettaglio e mostra un esempio.
Si noti che il secondo argomento di close()
è
un’estensione gawk
; non è disponibile in modalità compatibile
(vedi la sezione Opzioni sulla riga di comando).
fflush(
[nome_file])
Scrive su disco ogni output contenuto in memoria, associato con nome_file, che è o un file aperto in scrittura o un comando della shell che ridirige output a una pipe o a un coprocesso.
Molti programmi di utilità bufferizzano il loro output (cioè,
accumulano in memoria record da scrivere in un file su disco o sullo
schermo, fin quando non arriva il momento giusto per inviare i
dati al dispositivo di output).
Questo è spesso più efficiente che scrivere
ogni particella di informazione non appena diventa disponibile. Tuttavia,
qualche volta è necessario forzare un programma a svuotare
i suoi buffer (cioè, inviare l’informazione alla sua destinazione,
anche se un buffer non è pieno).
Questo è lo scopo della funzione fflush()
; anche
gawk
scrive il suo output in un buffer, e la funzione fflush()
forza gawk
a svuotare i suoi buffer.
Brian Kernighan ha aggiunto fflush()
al suo awk
nell’aprile
1992. Per due decenni è rimasta un’estensione comune. A Dicembre
2012 è stata accettata e inclusa nello standard POSIX.
Si veda il sito Web dell’Austin Group.
POSIX standardizza fflush()
come segue: se non c’è alcun
argomento, o se l’argomento è la stringa nulla (""
),
awk
svuota i buffer di tutti i file in output e di
tutte le pipe.
NOTA: Prima della versione 4.0.2,
gawk
avrebbe svuotato solo i buffer dello standard output se non era specificato alcun argomento, e svuotato tutti i buffer dei file in output e delle pipe se l’argomento era la stringa nulla. Questo è stato modificato per essere compatibile con l’awk
di Kernighan, nella speranza che standardizzare questa funzionalità in POSIX sarebbe stato più agevole (come poi è effettivamente successo).Con
gawk
, si può usare ‘fflush("/dev/stdout")’ se si desidera solo svuotare i buffer dello standard output.
fflush()
restituisce zero se il buffer è svuotato con successo;
altrimenti, restituisce un valore diverso da zero. (gawk
restituisce -1.)
Nel caso in cui tutti i buffer vadano svuotati, il valore restituito è zero
solo se tutti i buffer sono stati svuotati con successo. Altrimenti,
è -1, e gawk
avvisa riguardo al nome_file
che ha problemi.
gawk
invia anche un messaggio di avvertimento se si tenta di svuotare i
buffer di un file o pipe che era stato aperto in lettura
(p.es. con getline
),
o se nome_file non è un file, una pipe, o un coprocesso aperto.
in tal caso, fflush()
restituisce ancora -1.
Bufferizzazione interattiva e non interattiva
A complicare ulteriormente le cose, i problemi di bufferizzazione possono peggiorare se il programma eseguito è interattivo (cioè, se comunica con un utente seduto davanti a una tastiera).52 I programmi interattivi normalmente bufferizzano per riga il loro output (cioè, scrivono in output una riga alla volta). I programmi non-interattivi attendono di aver riempito un buffer, il che può voler dire anche parecchie righe di output. Ecco un esempio della differenza: $ awk '{ print $1 + $2 }' 1 1 -| 2 2 3 -| 5 Ctrl-d Ogni riga di output è stampata immediatamente. Si confronti questo comportamente con quello di questo esempio: $ awk '{ print $1 + $2 }' | cat 1 1 2 3 Ctrl-d -| 2 -| 5 In questo caso, nessun output viene stampato finché non è stato battuto il
Ctrl-d, perché l’output è bufferizzato e inviato tramite
pipe al comando |
system(comando)
Esegue il comando del sistema operativo comando e quindi
ritorna al programma awk
.
Restituisce il codice di ritorno di comando.
Per esempio, inserendo il seguente frammento di codice in un programma
awk
:
END { system("date | mail -s 'awk completato' root") }
all’amministratore di sistema viene inviato un messaggio di posta quando
il programma awk
termina di elaborare l’input e inizia
l’elaborazione da eseguire alla fine dell’input.
Si noti che la ridirezione di print
o printf
in una
pipe è spesso sufficiente per ottenere lo stesso risultato.
Se è necessario eseguire parecchi comandi, è più efficiente
stamparli verso una pipe diretta alla shell:
while (ancora lavoro da fare) print comando | "/bin/sh" close("/bin/sh")
Tuttavia, nel caso che il programma awk
sia interattivo,
system()
è utile per eseguire grossi programmi autonomi,
come ad esempio la shell o un programma di modifica testi.
Alcuni sistemi operativi non consentono di implementare la funzione
system()
.
Richiamare system()
in sistemi in cui non è disponibile provoca
un errore fatale.
NOTA: Quando si specifica l’opzione --sandbox, la funzione
system()
è disabilitata (vedi la sezione Opzioni sulla riga di comando).
Nei sistemi aderenti allo standard POSIX, il codice di ritorno di un
comando è un numero contenuto in 16 bit. Il valore del codice di ritorno
passato alla funzione C exit()
alla fine del programma è contenuto
negli 8 bit di valore più alto dei 16 bit (la metà sinistra) che compongono
il numero. I bit di valore più basso (la metà destra) indicano se il
processo è stato terminato da un segnale (bit 7), e, se questo è il caso,
il numero del segnale che ha provocato la terminazione (bit 0–6).
Tradizionalmente, la funzione system()
di awk
si è
semplicemente limitata a restituire il valore del codice di ritorno
diviso per 256 (ossia la metà sinistra del numero di 16 bit, spostata
a destra). In una situazione normale questo equivale a utilizzare il
codice di ritornodi system()
, ma nel caso in cui il programma sia
stato terminato da un segnale, il valore diventa un numero frazionale in
virgola mobile.53 POSIX stabilisce che la chiamata a system()
dall’interno
di awk
dovrebbe restituire l’intero valore a 16 bit.
gawk
si trova in qualche modo a metà strada.
I valori del codice di ritorno sono descritti nella
Tabella 9.5.
Situazione | Valore codice di ritorno da system() |
---|---|
--traditional | Valore dalla funzione C system() /256 |
--posix | Valore dalla funzione C system() |
Uscita normale dal comando | Codice di ritorno del comando |
Terminazione da un segnale | 256 + numero segnale "assassino" |
Terminazione da un segnale con dump memoria | 512 + numero segnale "assassino" |
Qualsiasi tipo di errore | -1 |
A partire dalla versione di agosto 2018, BWK awk
si comporta
come gawk
per il codice di ritorno della chiamata system()
.
Controllare la bufferizzazione dell’output con
system()
La funzione system("") # scrive l'output su disco
Avendo in mente le attese di un programmatore, sarebbe sensato che
BEGIN { print "prima riga stampata" system("echo system echo") print "seconda riga stampata" } deve stampare: prima riga stampata system echo seconda riga stampata e non: system echo prima riga stampata seconda riga stampata Se |
Un programma è interattivo se il suo standard output è connesso a un dispositivo terminale. Ai giorni nostri, questo vuol dire davanti a uno schermo e a una tastiera.
In uno scambio di messaggi privato il Dr. Kernighan mi ha comunicato che questo modo di procedere è probabilmente errato.
Successivo: Funzioni di tempo, Precedente: Funzioni per stringhe, Su: Funzioni predefinite [Contenuti][Indice]