Forum: PC Hard- und Software [Linux] Übliche Option für Ausgabe auf stdout?!


von Egon D. (Gast)


Lesenswert?

Schönen guten Abend!

Gegeben sei ein (selbstgeschriebenes) Programm, das
Daten aus einer Datei liest, sie verarbeitet und in
eine Zieldatei schreibt. Die Namen von Quell- und
Zieldatei werden wie üblich auf der Kommandozeile
angegeben. Das soll so sein und funktioniert.

Ich hätte jetzt gern die Möglichkeit, die Output-Daten
bei Bedarf auf die Standardausgabe zu schreiben. Gibt
es eine übliche Konvention für die Kommandozeilenoption,
mit der man das einschaltet? Mir fehlen irgendwie die
passenden Suchworte...

Das Ergebnis standardmäßig auf stdout schreiben möchte
ich nicht; das sind Binärdaten, und ich finde es immer
ärgerlich, wenn die Shell ohne Vorwarnung mit Binärdaten
geflutet wird.


Ach so: Sprache ist Pascal, Compiler ist FreePascal,
verwende keine FCL, falls das von Belang sein sollte.


Besten Dank für jeden hilfreichen Hinweis!

von Georg A. (georga)


Lesenswert?

Als Zieldatei einfach /dev/stdout angeben geht meistens oder stattdessen 
- als Ausgabefile (zB. -o -).

: Bearbeitet durch User
von Egon D. (Gast)


Lesenswert?

Georg A. schrieb:

> Als Zieldatei einfach /dev/stdout angeben geht meistens

Grmpf. Oh Gott!
Also das war ja jetzt echt zu einfach!

Danke.


> oder stattdessen - als Ausgabefile (zB. -o -).

Hmm.
Dann müsste ich konsequenterweise auch -i für das
Inputfile verwenden. Geht natürlich auch.

von Sheeva P. (sheevaplug)


Lesenswert?

Egon D. schrieb:
> Georg A. schrieb:
>> Als Zieldatei einfach /dev/stdout angeben geht meistens
>
> Grmpf. Oh Gott!

Da nicht für... ;-)

>> oder stattdessen - als Ausgabefile (zB. -o -).
>
> Hmm.
> Dann müsste ich konsequenterweise auch -i für das
> Inputfile verwenden. Geht natürlich auch.

Ja, nein, vielleicht... ich kenne mich mit Pascal nicht aus, unsere 
letzte Begegnung war zu meiner Schulzeit. Aber wenn es da so etwas wie 
"positional arguments" gibt, wie in boost::program_options für C++, oder 
in argparse für Python, dann sollte das kein Thema sein:
1
#!/usr/bin/env python
2
from argparse import ArgumentParser
3
4
5
if __name__ == '__main__':
6
    parser = ArgumentParser(description='command line arguments ;-)')
7
    parser.add_argument('infile', help='input file')
8
    parser.add_argument('outfile', help='output file')
9
    args = parser.parse_args()
10
11
    if args.infile == '-': args.infile = '/dev/stdin'
12
    if args.outfile == '-': args.outfile = '/dev/stdout'
13
14
    ### the rest is just... to actually DO sth ;-)
15
    
16
    counter = 0
17
    with open(args.infile, 'r') as ifh:
18
        with open(args.outfile, 'w') as ofh:
19
            for line in ifh:
20
                if line.strip().lower() == 'q':
21
                    break
22
                else:
23
                    ofh.write('%d: %s\n'%(counter, line.rstrip()))
24
                counter += 1

Dieses Programm kann man wie einen klassischen UNIX-Filter aufrufen:
1
./main.py - -

oder eben mit einem oder zwei Dateinamen. Ohne oder mit zuwenig 
Parametern gibt es hingegen eine übliche "Usage"-Ausgabe aus. HF!

von foobar (Gast)


Lesenswert?

>> oder stattdessen - als Ausgabefile (zB. -o -).
>
> Dann müsste ich konsequenterweise auch -i für das
> Inputfile verwenden.

Es geht ihm nicht um die Option sondern um das Minuszeichen.  Die 
Spezialdateien /dev/stdin|out gab es früher nicht.  Stattdessen gab es 
die Konvention, dafür den Dateinamen "-" zu nehmen.  Das Programm hat 
das explizit abgefragt und entspr Sonderbehandlung durchgeführt, z.B. 
so:
1
    FILE *fp = strcmp(filename,"-") ? fopen(filename,"w") : stdout;

Diese Konvention hat sich bis heute in vielen Programmen gehalten.

von Rolf M. (rmagnus)


Lesenswert?

Egon D. schrieb:
> Das Ergebnis standardmäßig auf stdout schreiben möchte
> ich nicht; das sind Binärdaten, und ich finde es immer
> ärgerlich, wenn die Shell ohne Vorwarnung mit Binärdaten
> geflutet wird.

Einige Programme wie z.B. tar machen das trotzdem, prüfen aber vorher, 
ob stdout an ein Terminal geht und brechen dann automatisch ab.
Wie das in Pascal geht, weiß ich nicht, aber ich gehe davon aus, dass 
dir die Posix-Funktion isatty dort auch zur Verfügung steht. In C würde 
die Überprüfung so aussehen:
1
bool output_is_terminal = isatty(fileno(stdout));
nehmen.

: Bearbeitet durch User
von foobaz (Gast)


Lesenswert?

> Die Spezialdateien /dev/stdin|out gab es früher nicht.

Jedes Kleinkind weiss, das die Filedeskriptoren dafuer 1 und 2
sind/waren, respektive 3 fuer stderr.
Und das der gestartete Prozess die bereits geoeffneten Deskriptoren
mit in die Wiege gelegt bekommen hat, was ein weiteres "Oeffnen"
voelling unnoetig macht/e.

von Rollo (Gast)


Lesenswert?

foobaz schrieb:
> Und das der gestartete Prozess die bereits geoeffneten Deskriptoren
> mit in die Wiege gelegt bekommen hat, was ein weiteres "Oeffnen"
> voelling unnoetig macht/e.

Das ist nicht zwingend.

von foobaz (Gast)


Lesenswert?

> Das ist nicht zwingend.

Aber in 99.99 % der Faelle zutreffend.
Nicht jeder zieht sich die Hose mit der (exec-)Kneifzange an.
Nur 0.01 % tun das.

von Georg A. (georga)


Lesenswert?

foobaz schrieb:
> Jedes Kleinkind weiss, das die Filedeskriptoren dafuer 1 und 2
> sind/waren, respektive 3 fuer stderr.

Frag bitte die Kleinkinder nochmal, du weisst es anscheinend nicht genau 
;)

von Klaus W. (mfgkw)


Lesenswert?

Zwischen Kleinkind und Erwachsenem hat man einige Gelegenheiten, noch 
was zu lernen und ggf. zu korrigieren :-)

von foobaz (Gast)


Lesenswert?

Hmm ja, es sind 1 (stdout) und 2 (stderr).
Aber dafuer gibt es ja Headerdateien damit mann sich solchen
Kleinkram nicht merken muss.

von Georg A. (georga)


Lesenswert?

Die Sache mit dem expliziten Check auf - vs /dev/stdout hätte den 
Vorteil, dass man es auch unter Windows identisch nutzen kann.

von Rolf M. (rmagnus)


Lesenswert?

foobaz schrieb:
> Hmm ja, es sind 1 (stdout) und 2 (stderr).
> Aber dafuer gibt es ja Headerdateien damit mann sich solchen Kleinkram
> nicht merken muss.

Ja, man kann entweder wie gezeigt die Funktion fileno() verwenden, oder 
man nutzt Makros wie STDOUT_FILENO aus unistd.h. Das gilt allerdings für 
C und wird in Pascal sicherlich anders aussehen.

von 🐧 DPA 🐧 (Gast)


Lesenswert?

fileno(stdout) ist nicht äquivalent zu 1 btw. STDOUT_FILENO.
Is it möglich sachen wie z.B. stdout=fopen(...) zu machen, dann ist 
fileno(stdout) was anderes.

von Kleinkind (Gast)


Lesenswert?

Ich sehe immer 0, 1 und 2 und nicht 1, 2 und 3

von Rolf M. (rmagnus)


Lesenswert?

🐧 DPA 🐧 schrieb:
> Is it möglich sachen wie z.B. stdout=fopen(...) zu machen

Das kann funktionieren, muss aber nicht. Deshalb gibt es die Funktion 
freopen() und in POSIX noch fdopen().
Generell halte ich es aber für keine gute Idee, stdout auf irgendwas 
anderes als 1 umzubiegen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.