10

I uploaded some font files to AWS (running Amazon Linux) and moved them to the /usr/share/fonts directory using a cp command in .ebextensions.

When I SSH in from my mac and use ls -a, I see some files are colored differently - one set of font files is black while others are green. I'm curious what caused this to be so, and if it will create any problems for my code.

fonts directory on Elastic Beanstalk running AWS Linux

ls -la screenshot

From another answer on AskUbuntu I found this key on how to interpret these colours. I can't understand why a .ttf would be executable or why one set of .ttfs would be recognized and not another.

Blue: Directory

Green: Executable or recognized data file

Sky Blue: Linked file

Yellow with black background: Device

Pink: Graphic image file

Red: Archive file

These files were all downloaded to a mac from various font sites before uploading.

  • 4
    The specific colors (blue, pink, etc) don't mean anything. You can customize the colors to be whatever you want. linux-sxs.org/housekeeping/lscolors.html To check the colors for your specific system, echo $LS_COLORS – beardedlinuxgeek Jun 12 '17 at 7:04
  • To clarify, my intent was not really about the colors per se, but to understand if this indicates I will face any problems with my scripts/code. – Pranab Jun 12 '17 at 7:09
13

ls -l will tell you definitively whether a file is executable or not. I don't think there's any great mystery here. You downloaded files from various sources each of which might have had different permission bits set (for no particular reason). If you don't like seeing some with colors and others without try chmod -x *.ttf...font files should not need the executable bit set.

  • 1
    Exactly. The only difference between a regular file which has 'executable' permission set, and one which is not, is that when you try to run the file from command line, for file with x bit set, OS will try to use a program, if any such is defined in system, to open that file. – Gnudiff Jun 12 '17 at 7:04
  • 2
    @Pranab no, for fonts there should not be any difference. – Gnudiff Jun 12 '17 at 7:07
  • 1
    @Pranab Glad I could help. When I am at a proper computer with keyboard, I will try to make a bit more informative answer, so that there is a broader context available. – Gnudiff Jun 12 '17 at 7:27
  • 1
    Actually, I'd rather not mislead someone who doesn't know otherwise so here's my original comment minus the wrong bits: There are various reasons why the bit might be set..if anywhere along the line someone turns on the executable bit then that could "follow" the file around. (This presumes that each person that copies it preserves those original bits.) It's pretty much harmless in any case. – B Layer Jun 12 '17 at 10:06
  • 12
    Most probably they were copied from a FAT or NTFS volume, which don't store the executable bit, so are mounted by default so that all files have the executable bit set. – Matteo Italia Jun 12 '17 at 14:42
6

It seems like the ls command you are executing is an alias for ls --color

man ls

--color[=WHEN] colorize the output; WHEN can be 'always' (default if omitted), 'auto', or 'never'; more info below

You can check it by running the origin ls:

  • Using quotes:

    "ls" -a

  • Using full path (e.g. if ls location is in /bin/ls) and see if it shows the colors or not:

    /bin/ls -a

Note: running ls -la will show you the details of the files, and you'll be able to see the full details of each file, which will allow you to check with the expected output of ls --color

  • It's interesting how many ways there are to get to the core command. I wasn't aware of the surround-with-quotes method. At least with bash, one can also precede the command with backslash, \ls -a, or use the 'command' builtin, command ls -a. If you want to see how a command resolves, rather than run it, there is type -a ls. – B Layer Jun 12 '17 at 7:56
  • @BlairM. the quotes and backslash methods only prevent alias expansion. They won't have any effect if you have a shell function or builtin called ls. – shadowtalker Jun 12 '17 at 19:28
  • @ssdecontrol Right. I didn't mean to suggest otherwise...we were talking about aliases with respect to ls. But it's good information. – B Layer Jun 13 '17 at 9:32
4

The color is indicating that the file is marked as "executable"*

The executable permission bits (one for user, one for group, one for other) means that if the name of the file is passed to one of the exec system call the kernel will go ahead and try and exectute it.

Convention is that only files that are actually intended to be exectuted have the executable bit set. However when moving/copying files around, especially in a multiplatform environment it is easy to inadvertantly gain or lose the executable bits.

Files stored on a filesystem that doesn't support unix permissions (fat, ntfs etc) are likely to appear to the system as executable. Moving or copying these files to a unix filesystem using a tool that preserves permissions will then preserve those executable bits.

On the other hand using tools to move files that either can't preserve permissions or are used with the option to preserve permissions deselected is likely to result in the copy not being marked as executable even though the original was.

So after being moved around a variety of platforms using a variety of tools the executable permission bits can end up in a fairly arbitrary state.

* I'm not 100% sure how ls handles the case where some but not all of the executable bits are set.

2

As previous answers said, the coloring is to indicate whether the files are considered executable or not.

The "execute" permission (=bit) in Linux and most other Unixes has one meaning for files and another for directories.

For directories, if you have execute permission to it, you can see its contents. If you don't, you can't cd to the directory, nor you can list files in it, even if you have both read and write access to directory.

For regular files (as opposed to device files and other special Unix file types), the execute bit means that if you use the filename on command line, the O/S (or more precisely: shell) will try to "execute" or run the file as a command. Conversely, if you don't have execute permission on the file, you can't run it from command line.

So, if you, for example, remove the x permission from all users on /bin/cat file (which is a Unix command) you yourself or anybody else and any program that tries to use "cat" command will fail.

Those are then the OS commands, such as "cat" and "grep", which have executeble files usally in /*/bin/ directories -- /bin, /usr/bin, /sbin, /usr/sbin etc.

And then there can be uncompiled, interpreted scripts, which are either written in some programming language, such as Python or shell scripts (basically, commands you write as if from commandline when sshing to server).

Now, when you set execute bit on the script file (for example, file foobar), and try to execute it by your shell: "./foobar", the shell tries to analyze the file and find the correct program to pass the script to.

This the shell does by trying to read the file's first line and finding the "shebang" notation of which program this is supposed to run.

So, if your foobar was a text file with the first line like this:

#!/usr/bin/python

Then shell would try to execute command: /usr/bin/python foobar , basically invoking python interpreter and passing the name of your foobar file to it as a Python script.

If shell wouldn't find such first line in your file, it would then try to execute foobar itself as if it contained shell commands.

If the file with executable bit does not contain valid shell commands though, the shell would simply complain.

So this is what would happen, if you have TTF files with exec bit set and tried to run it from command line:

$./FreeMonoOblique.ttf
-bash: ./FreeMonoOblique.ttf: cannot execute binary file: Exec format error
$

So, for fonts, it is probably neater, if the exec bit is not set, but doesn't really change anything.

P.S. Just some extraneous information. If you do remove the execute bit on some command or script, it might still be passed to any other program as an argument. If that other program knows, how to execute your command, your removal of exec bit didn't really matter. For example, the foobar Python script would still be run by Python interpreter, if you simply did from command line:

$python foobar

instead of

$./foobar

Same with the example of the system commands, such as "cat". If you remove exec bit from "cat", you can still pass it to a new instance of shell for execution:

$sh -c 'cat myfile'

will work, even if you have removed exec bit from cat and

$cat myfile

doesn't.

  • 2
    On my system, at least, unsetting the executable bit on a binary executable file like cat or echo does not let you run it via sh -c 'cat myfile', nor with system("cat", "myfile") in languages like Ruby. The reason Python can run non-executable .py files is because it reads them in as a string of text, and then uses an interpreter to make that text behave as if it's code. – Ethan Kaminski Jun 12 '17 at 11:12
  • @EthanKaminski Interesting. I distinctly remember it working for me, but will have to check the details. – Gnudiff Jun 12 '17 at 14:53
  • 1
    @Gnudiff For binary executables, the execve system call insists on execute permission. On glibc-based systems you can invoke the dynamic linker as a program to get approximately the same effect as a shebang line (/lib64/ld-linux-x86-64.so.2 /bin/cat) and this works for me even if the file on the command line isn't executable, but sh -c cat won't do that for you. – zwol Jun 12 '17 at 15:14
  • It's not the shell that determines whether and how to exectute a file, it's the kernel. The shell just passes the executable name and parameters to the kernel. – plugwash Jun 13 '17 at 13:57

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.