Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is it possible to make ls distinguish executable scripts from actual compiled binaries?

The permissions are most often the same (+x), and with ls -F you get an asterisk suffix (*) for both, so it's hard to tell them apart. I have a script to setup the colors of ls, but it relies on the file being executable or not, so they show up the same:

BG='01;32'  # green
EX="ex=$BG" # file with execute permission

I don't want to depend on the extension as so many of these files don't have it.

I want this so when I see some bizarre error message and think, "What code caused that?", I know whether or not it's safe to cat the file.

If there is no standard solution, what about parsing the output of file, in one common function, and inserting some distinctive mark? Or would that be much too slow for ls?

share|improve this question
At the bare minimum you'll probably have to check (as in read) the first 2 bytes of every executable file you ls (#! probably means script, ^?E probably means the start of a binary). How much of an effect this has probably depends on things like your file system and directory layout and whether you are using spinning disks or solid state, etc. If you do that you probably want noatime or relatime. I think it would be much easier to just run file manually on the few files you want to inspect, unless you truly want to do this for every ls. – jw013 Nov 6 '12 at 19:36
@jw013: Hm, maybe it is smarter to base that check on cat, and not ls? I could call it ct or something similar so it won't interfere with other use of cat. – Emanuel Berg Nov 6 '12 at 19:55
That's probably a better way to go - replace cat with a shell function that checks if it's a binary file first and warns before outputting to a terminal. I think less already does this check. – jw013 Nov 6 '12 at 20:04
Why do you need this for every file? Just check file before catting something – BIGTRONICA Jul 8 '14 at 17:14
up vote 1 down vote accepted

You need to look at the contents of a file to distinguish between binaries and scripts. ls won't do this, it only looks at file names and metadata (type, permission, etc.).

Here's a crude parser for file that colors scripts and binaries differently. It acts like ls -d; adding metadata would require a patch-up job that calls for a more direct approach (e.g. in Perl or Python); use lsx somedir/* to list the contents of a directory. File names are assumed not to contain newlines nor colons (you can change the : separator for some other string with the -F option to file).

lsx () {
  file -iN -- "$@" |
  while IFS= read -r line; do
    name=${line%%: *}; type=${line#*: }
    case $type in
      application/x-executable*) color='32';;
      text/x-shellscript*) color='01;32';;
      application/*zip*) color='31';;
    printf '\033[%sm%s\033[0m\n' "$color" "$name"
share|improve this answer

You could play around with dircolors. Have a look at the output of dircolors -p. On my systems I find the following relevant definitions:

# This is for files with execute permission:
EXEC 01;32
# Or if you want to colorize scripts even if they do not have the
# executable bit actually set.
#.sh 01;32

If you remove the # at the last line and write .sh 07;31 your shell scripts (all files with extension .sh) will blink in red color.

Save your settings in ~/.dircolors and add to your .bashrc the line:

eval "$(dircolor $HOME/.dircolors)"
share|improve this answer
Yes, I'm aware of this. It's very far from a silver bullet solution (as I said, a lot of scripts don't have extensions), and those who do... well, you already know they are scripts (unless you go crazy naming binaries)! Right now, I can't see how this would help me but ... what the heck, I've been wrong before. +1 – Emanuel Berg Nov 6 '12 at 20:41
Sorry, I didn't read about your naming schemes. However in that case you have to check the output of file. I would assume that zsh has a solution for your case, but I'm not sure about this. – qbi Nov 6 '12 at 20:46

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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