Bash: turn off flashing symlink with permission errors (Amazon EC2)

amazon-ec2, amazon-web-services, bash

Solution

Why does it do this?

I agree with you that blinking red text is a pretty inappropriate default for something that is sometimes not an error condition at all, and rarely as severe an error as its level of intrusiveness (compared to almost all other terminal output) implies.

Your case — linking to files you don't always have read access to — is one such non-error condition. Mine is another: I have symbolic links to various directories under the mount point of my phone's SD card; the links are convenient when the phone is connected, and useless but innocuous otherwise. I have no need of the terminal visually "screaming" at me just because the SD card isn't mounted. I already know, terminal. It's fine. Chill.

Someone ought to lobby to have this irrational default changed. (It won't be me; I already have too many irons in too many fires.) But the happy news is that it's easy to override in your own environment.

How can I make it stop?

The blinking is specified by parameters encoded in the `LS_COLORS` environment variable.

In all probability, your `/etc/bashrc` is setting `LS_COLORS`, but you can override this setting in your own environment without having to alter `/etc/bashrc`.

You should first look at `/etc/bashrc` to see how it is setting `LS_COLORS`. It's likely doing this via `dircolors` — and, if you're lucky, it is first looking for a file for those settings before falling back to the defaults. For instance, my system's (unaltered) `/etc/bashrc` contains the lines

    if [[ -f ~/.dir_colors ]] ; then
            eval "$(dircolors -b ~/.dir_colors)"
    elif [[ -f /etc/DIR_COLORS ]] ; then
            eval "$(dircolors -b /etc/DIR_COLORS)"
    else
            eval "$(dircolors -b)"
    fi

This means that to change the colors `ls` uses, I can edit (or create, if it doesn't exist) `~/.dir_colors` or `/etc/DIR_COLORS`.

As it happens, my system is very accommodating, providing a well-commented `/etc/DIR_COLORS`. Here are some relevant lines:

# Attribute codes:
# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
# Text color codes:
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
# Background color codes:
# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
...
ORPHAN 01;05;37;41  # symlink to nonexistent file, or non-stat'able file ...
MISSING 01;05;37;41 # ... and the files they point to

With this, it's easy to tell that, to remove the "blink" attribute from broken symbolic links, you need to take the `05` out of the `ORPHAN` and `MISSING` lines. Personally, I also changed the colors, because even the reverse video highlighted such files far more than warranted. Once you know where to look, it's easy to customize to taste.

If neither of these files exists, not to worry: `dircolors` has a `-p` option that outputs a default version of this file.

If your `/etc/bashrc` runs `dircolors` but does not check any files, relying only on the command's defaults, you can override it in your own `.bashrc` by including a line like one of the above, such as `eval "$(dircolors -b ~/.dir_colors)"`.

Finally, what if your system doesn't have a `dircolors` command at all, instead having `/etc/bashrc` set `LS_COLORS` to some hard-coded value? It's more of a hassle, but you can still monkey with this environment variable directly. Like `PATH`, it's a colon-separated list of elements — fairly impenetrable to look at all at once, but easier if you change the colons to newlines:

$ echo $LS_COLORS | tr : \\012

The relevant values are `or` (ORPHAN) and `mi` (MISSING). On my system, by default these come up as:

$ echo $LS_COLORS | tr : \\012 | egrep '^(or|mi)'
or=01;05;37;41
mi=01;05;37;41

You can hard-code your own value for `LS_COLORS` in your `.bashrc`, adjusting values as desired (see the key above), or you can use the system default but modify select values with `sed`. For instance, to set only the bold attribute for such links but remove the blinking and color-changing:

LS_COLORS=$(echo $LS_COLORS | sed -E 's/:(or|mi)=[^:]+/:\1=01/g')

Now running the same command as above produces:

$ echo $LS_COLORS | tr : \\012 | egrep '^(or|mi)'
or=01
mi=01

Problem

I deliberately created soft links to files I have sudo access to. When performing the ls -la command, bash insists on the target flashing red as though the links are broken (I need to sudo for access). Flashing text is the worst, and I don't want to edit the /etc/bashrc (Amazon EC2 appears to source this file from ~/.bashrc) file which I think may be setting the colours. Any ideas on removing the flashing without removing/touching the /etc/bashrc.

Original source