Bei Ausgabeumlenkung verschwinden Steuerzeichen (Linux)

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
Antworten
Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Bei Ausgabeumlenkung verschwinden Steuerzeichen (Linux)

Beitrag von Mathias »

Als Beispiel, wen ich "ls" eingebe, habe ich eine Bunte Darstellung auf der Konsole.
Wie die meisten Linux-Profis wissen, wir die farbige Darstellung über Escape-Sequenzen gesteuert.
Wen ich aber

Code: Alles auswählen

ls >> test.txt
eingebe, sind diese Steuerzeichen verschwunden.
Wie wird dies intern bei ls gelöst, so das es erkannt, ob die Ausgabe auf die Konsole oder in eine Datei ist.
Nehme ich als Beispiel die fpc-Konsolen GUI, sieht man gut, das dies dort nicht abgefangen wird.
Wen ich folgendes mache

Code: Alles auswählen

fp >> test.txt
Habe ich folgende Ausgabe:

Code: Alles auswählen

[H[?12l[?25h[?12;25h[?1049h[?12l[?25h(B)0[0m[H[2J[0;40;37m[?7l[1;1H[90;47m 
[0;40;37m[?7l[2;1H[34;47m░░░░░░░░░░░░░░░░
Auf das Problem bin ich mit folgendem Test-Programm gestossen:

Code: Alles auswählen

uses
  Unix;
var
  f: Text;
  s: string;
  i: integer = 1;
begin
  popen(f, 'ls /home/tux', 'R');
  while not EOF(f) do begin
    ReadLn(f, s);
    WriteLn(i: 4, ': ', s);
    Inc(i);
  end;
  PClose(f);
end. 
Hier sieht man auch gut, das die Escape-Sequenzen verschwunden sind. Wen ich mit "ls --color" die Farben erzwinge, kommt es dann auch farbig. So nebenbei verschwinden auch Steuerzeichen wie Tab und Enter, ab dies denke liegt am Einlesen mit ReadLn().
Aber bei der Datei-Umlenkung, nützt auch --color nichts.

Wie kann ich selbst ermitteln, wen ich eine Konsolenanwendung schreibe, wohin die Daten mit WriteLn gehen, so wie es ls auch macht ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10499
Registriert: Mo 11. Sep 2006, 19:01

Re: Bei Ausgabeumlenkung verschwinden Steuerzeichen (Linux)

Beitrag von theo »

Ich glaube, das macht die Shell, nicht ls.
Farbig

Code: Alles auswählen

/bin/ls
Monochrom

Code: Alles auswählen

/bin/ls --color
Farbig

S.a. https://superuser.com/questions/543105/ ... s-in-linux

Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Bei Ausgabeumlenkung verschwinden Steuerzeichen (Linux)

Beitrag von Mathias »

Ich glaube, das macht die Shell, nicht ls.
Ich denke, es macht "ls" selbst.
Folgende Demo würde dies beweisen:
FpIOCtl(STDOUT_FILENO, TIOCGWINSZ, @w);
WriteLn(w.ws_col, 'x', w.ws_row);
Auf der Konsole werden die Koordinaten des Terminal-Fensters ausgegeben.
Leite ich die Ausgabe in eine Datei im, kommt nur "0x0", genau das Selbe auf der Debugging-Console von Lazarus.

Somit muss wohl ls interen auch ein IOCtl oder was ähnlich ausführen.

Was mir noch aufgefallen ist. Ein ls ohne Parameter gibt in der Konsole die schön sortierten Blöcke aus. welche in der Senkrechte sortiert sind. Bei der Umlenken, kommt alles an einem Schlauch raus.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 834
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Bei Ausgabeumlenkung verschwinden Steuerzeichen (Linux)

Beitrag von PascalDragon »

Mathias hat geschrieben:
So 30. Apr 2023, 13:23
Wie kann ich selbst ermitteln, wen ich eine Konsolenanwendung schreibe, wohin die Daten mit WriteLn gehen, so wie es ls auch macht ?
Du kannst dafür entweder die POSIX Funktion isatty() in Unit TermIO oder fpfstat aus der Unit BaseUnix nutzen. Im Fall von StdOut ist der zu verwendende File Deskriptor 1. Bei fpfstat überprüfst du es dann so wie es die RTL-interne Funktion do_isdevice macht:

Code: Alles auswählen

Function Do_IsDevice(Handle:THandle):boolean;
var
  StatRec: Stat;
begin
  fpFStat (Handle, StatRec);
  case StatRec.st_Mode and S_IFMT of
   S_IFCHR, S_IFIFO, S_IFSOCK: Do_IsDevice := true
  else
   Do_IsDevice := false;
  end;
end;
FPC Compiler Entwickler

Antworten