3

I'd like to know which control sequences are sent to bash by programs to format their outputs.

For example, if I dump man less I can discern which parts are bold or underlined.

DDEESSCCRRIIPPTTIIOONN
       _L_e_s_s is a program similar to _m_o_r_e (1), but which allows backward  move-
       ment in the file as well as forward movement.

But if I send ls -G's output to a file there's no data regarding its colors format.

I'm using Mac OS X.

4

Use script /tmp/output to start recording in a new shell, then type your commands and look in the /tmp/output file, e.g. with an editor or cat -vet. Type exit to the shell to exit the recording.

4
  • Great answer! One detail though is, my aliases and functions stopped working after running script. My /etc/profile sources env vars, aliases and functions from a file in a custom location.
    – 1.61803
    Aug 30 '15 at 18:33
  • By default, script uses $SHELL as the command to run. You might have more success starting a login shell, eg script -c 'bash -l' /tmp/output.
    – meuh
    Aug 30 '15 at 18:40
  • My version of script doesn't have -c option, but allows the syntax script [-akq] [-t time] [file [command ...]] so script typescript bash -l works fine.
    – 1.61803
    Aug 30 '15 at 20:20
  • btw, for cat, -e is equivalent to -vE and -t is equivalent to -vT - so -et is the same as -vet or -vET. For understanding the coloring, -v should suffice, the others only add control characters for Tab and EOL, which can be more annoying than helpful.
    – xeruf
    Jun 7 '20 at 17:32
3

Probably best to run the output through a hex viewer (e.g. od, hexdump, xxd):

% man less | hexdump -C | head -5
00000000  4c 45 53 53 28 31 29 20  20 20 20 20 20 20 20 20  |LESS(1)         |
00000010  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
*
00000040  20 20 20 20 20 20 20 4c  45 53 53 28 31 29 0a 0a  |       LESS(1)..|
00000050  0a 0a 4e 08 4e 41 08 41  4d 08 4d 45 08 45 0a 20  |..N.NA.AM.ME.E. |
% 

As then you can lookup any non-printable characters in ascii(7).

As for the "doesn't work" nonsense, a quick look through the ls(1) manual results in:

% env TERM=xterm-color CLICOLOR_FORCE=1 ls -G | hexdump -C | head -3
00000000  1b 5b 33 34 6d 41 70 70  6c 69 63 61 74 69 6f 6e  |.[34mApplication|
00000010  73 1b 5b 6d 1b 5b 6d 0a  1b 5b 33 34 6d 44 65 73  |s.[m.[m..[34mDes|
00000020  6b 74 6f 70 1b 5b 6d 1b  5b 6d 0a 1b 5b 33 34 6d  |ktop.[m.[m..[34m|
% 
3
  • That doesn't seem to work.
    – 1.61803
    Aug 30 '15 at 15:36
  • @1.61803 The version of bash is irrelevant, it is not involved here. What's relevant is that you're on OSX. Aug 30 '15 at 23:27
  • cat -v seems much more handy than hexdump tbh
    – xeruf
    Jun 7 '20 at 17:35
3

For ls you can do

export CLICOLOR_FORCE=X
ls -G | cat -vet
3
  • That's a great answer, too! What does the value X of CLICOLOR_FORCE actually do? I searched the man pages but only ls refers to it, but doesn't tell anything about that or any value. If I set to any other value it has the same effect.
    – 1.61803
    Sep 1 '15 at 15:16
  • @1.61803 or would you prefer golden mean- The X set the value of CLICOLOR_FORCE to a value other than null, as you found out.
    – fd0
    Sep 1 '15 at 16:15
  • phi is always better. I just couldn't find a reference for setting the var to not null. I just made this an aliased function in my profile. Thanks.
    – 1.61803
    Sep 1 '15 at 19:27
3

Most core utilities behave differently when they output to an interactive terminal. If they detect you are outputting into a file or a pipe, they don't format (reasonably so: we don't want color escape sequences when we are processing file lists with a script). For ls, you can force it:

CLICOLOR_FORCE=1 ls -G

(That's for OSX; on Linux, that would be ls --color=always.)

Other tools have similar switches (grep, for instance).

11
  • 1
    I know about the switches. What I want to achieve is display the stream of chars with control sequences sent to the display by a program.
    – 1.61803
    Aug 30 '15 at 14:53
  • 1
    The question was how can you get the raw formatting output.
    – MichalH
    Aug 30 '15 at 14:53
  • @1.61803 Doesn't ls --color=always >file do what you want?
    – jimmij
    Aug 30 '15 at 15:02
  • @jimmij, no, in bash 3.2.53(1)-release (x86_64-apple-darwin12) I get only text without any control sequence
    – 1.61803
    Aug 30 '15 at 15:25
  • 2
    @1.61803 oh, wait, you have apple, so ls -G instead of ls --color=always is the way to go. And concerning control characters - try ls -G | cat -vte.
    – jimmij
    Aug 30 '15 at 15:36
0

Maybe a simple:

 $ ls --color=always  |  od -cAn

will be enough.

0

The simple solutions are somewhat hidden among the existing answers and comments, so let me sum it up:

Sending the sequences

Programs that send formatting sequences only send them in interactive terminals by default, to not clutter automation. So unless you use script as outlined in this answer (works always, but can be a little more verbose and complicated to set up), you need to force your program to always output its formatting sequences, regardless of where the output is going.

In the case of ls, use ls -G on Mac and ls --color on Linux. Common utilities, another example is git, usually have such a flag.

If that is not available, you can trick the program into thinking it outputs to a tty.

Viewing the sequences

Pipe the output into cat -v, e.g. ls -G | cat -v

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.