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!
Als Zieldatei einfach /dev/stdout angeben geht meistens oder stattdessen - als Ausgabefile (zB. -o -).
:
Bearbeitet durch User
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.
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!
>> 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.
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
> 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.
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.
> 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.
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 ;)
Zwischen Kleinkind und Erwachsenem hat man einige Gelegenheiten, noch was zu lernen und ggf. zu korrigieren :-)
Hmm ja, es sind 1 (stdout) und 2 (stderr). Aber dafuer gibt es ja Headerdateien damit mann sich solchen Kleinkram nicht merken muss.
Die Sache mit dem expliziten Check auf - vs /dev/stdout hätte den Vorteil, dass man es auch unter Windows identisch nutzen kann.
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.
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.
🐧 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.