(ar)ch (pa)ckages – a generic package tasks script for Arch Linux

I once saw a wrapper-script for pacman in the forums that was basically a short-hand version of common pacman tasks. I thought this was a good idea and over the last couple years, I’ve expanded on it. It does just about everything I need it to. It’s real basic and I call it arpa. Here is a basic synopsis:

arpa [option] [*package] - a generic package tasks wrapper script
  -e, --explicit - install a package as explicit
  -g, --get      - get/download package upgrade(s)    : -G get pkg upgrades all
  -i, --install  - install a package                  : -I install as dependency
  -l, --list     - list package files                 : -L list pkgs installed
  -o, --owns     - owning package of a file
  -q, --query    - query for an installed package     : -Q query w/ description
  -r, --remove   - remove a pkg and its deps          : -R force, no argue orphs
  -s, --search   - search for a package               : -S search w/ description
  -u, --upgrade  - upgrade system                     : -U upgrade AUR
  -y, --sync     - sync package db

Good for me to have this around so I can remember everything :), and it is in the AUR.

Syntax Highlighting in Blog Posts with Vim

Update: Reader Elder Marco has pointed out that WordPress.com does have support for syntax highlighting of source code built-in (which I had never heard of before) that might be a preferred alternative for some. An example of both is below.

Vim is a great all-around editor, it also does very good at syntax highlighting. With the plugin “TOhtml” included with Vim it’s easy to put that highlighting into a blog post. I created a blogscrpt bash script that when run on another script will produce a file defining the syntax highlighting in HTML code. From there it can be pasted into the blog post.

blogscrpt syntax highlighting:

#!/bin/bash
# Create HTML code from Vim syntax highlighting (for use in coloring scripts)

filename=$@
background=light
colorscheme=beauty256
scrpt=${0##*/}  # filename of script

# Display usage if no parameters given
if [[ -z "$@" ]]; then
  echo " $scrpt <filename> - create HTML code from Vim syntax highlighting"
  exit
fi

# Syntax highlighting to HTML export
vim -f  +"syntax on"                  \
        +"set background=$background" \
        +"colorscheme $colorscheme"   \
        +"let html_use_css = 0"       \
        +"let html_no_pre = 1"        \
        +"let html_number_lines = 0"  \
        +"TOhtml"                     \
        +"x"                          \
        +"q" $filename

# Clean up HTML code
tidy -utf8 -f /dev/null --wrap -m $filename.html

# Delete the HTML meta page information.
sed -i '1,/body bgcolor=/d' $filename.html

# Remove line breaks (needed for some things like blog posts)
sed -i 's|<br>||g' $filename.html

# Remove the closing HTML tags
sed -i 's~</body[^>]*>~~g' $filename.html
sed -i 's~</html[^>]*>~~g' $filename.html

# Add preformatting tabs <pre> and </pre>
#sed -i '1 i <pre>' $filename.html
#sed -i '$ a </pre>' $filename.html

# Remove trailing blank lines
while [ "$(tail -n 1 $filename.html)" == "\n" ]; do
  sed -i '$d' $filename.html
done

# Delete newline of last <font> line for better formatting
sed -i ':a;N;$!ba;s/\(.*\)\n/\1/' $filename.html
sed -i ':a;N;$!ba;s/\(.*\)\n/\1/' $filename.html

# Delete final newline
perl -i -e 'local $/; $_ = <>; s/\n$//; print' $filename.html

WordPress built-in syntax highlight support example:

#!/bin/bash
# Create HTML code from Vim syntax highlighting (for use in coloring scripts)

filename=$@
background=light
colorscheme=beauty256
scrpt=${0##*/}  # filename of script

# Display usage if no parameters given
if [[ -z "$@" ]]; then
  echo " $scrpt <filename> - create HTML code from Vim syntax highlighting"
  exit
fi

# Syntax highlighting to HTML export
vim -f  +"syntax on"                  \
        +"set background=$background" \
        +"colorscheme $colorscheme"   \
        +"let html_use_css = 0"       \
        +"let html_no_pre = 1"        \
        +"let html_number_lines = 0"  \
        +"TOhtml"                     \
        +"x"                          \
        +"q" $filename

# Clean up HTML code
tidy -utf8 -f /dev/null --wrap -m $filename.html

# Delete the HTML meta page information.
sed -i '1,/body bgcolor=/d' $filename.html

# Remove line breaks (needed for some things like blog posts)
sed -i 's|<br>||g' $filename.html

# Remove the closing HTML tags
sed -i 's~</body[^>]*>~~g' $filename.html
sed -i 's~</html[^>]*>~~g' $filename.html

# Add preformatting tabs <pre> and </pre>
#sed -i '1 i <pre>' $filename.html
#sed -i '$ a </pre>' $filename.html

# Remove trailing blank lines
while [ "$(tail -n 1 $filename.html)" == "\n" ]; do
  sed -i '$d' $filename.html
done

# Delete newline of last <font> line for better formatting
sed -i ':a;N;$!ba;s/\(.*\)\n/\1/' $filename.html
sed -i ':a;N;$!ba;s/\(.*\)\n/\1/' $filename.html

# Delete final newline
perl -i -e 'local $/; $_ = <>; s/\n$//; print' $filename.html

DisplaySize in xorg.conf… uhgg!

Update: This turns out to be done by xrandr which the X.org server hands off to now for dynamic use of monitors. man xrandr even reports that it is trying to keepaconstant DPI. Not sure just why it is doing it, but found a good way to get it done.

I just got a new monitor to be able to use as an external monitor for my laptop. While I was setting it up I noticed that the monitors display size wasn’t correctly detected. The Xorg server does a good job auto-configuring however this caught my eye:

xdpyinfo | grep -B2 resolution
dimensions:    1920x1080 pixels (508x286 millimeters)
resolution:    96x96 dots per inch

The monitor I got is a 21.5″ monitor so I figured the DPI was off. I decided to calculate it myself (this is a square pixel monitor):

res_horz=1920
res_vert=1080
res_diag=$(echo "scale=5;sqrt($res_horz^2+$res_vert^2)" | bc)
siz_diag=21.5
siz_horz=$(echo "scale=5;($siz_diag/$res_diag)*$res_horz*25.4" | bc)
siz_vert=$(echo "scale=5;($siz_diag/$res_diag)*$res_vert*25.4" | bc)
echo "$siz_horz"x"$siz_vert"
475.48800x267.46200

Also there are online DPI Calculators conferred by doubt (1, 2,) and xrandr:

em_ds_h=$(xrandr | grep VGA-0 | rev | cut -d " " -f 3 | rev | sed 's/mm//')
em_ds_v=$(xrandr | grep VGA-0 | rev | cut -d " " -f 1 | rev | sed 's/mm//')
em_ds="$em_ds_h"x"$em_ds_v"
echo $em_ds
477x268

My discovered value and theirs are a couple millimeters off overall so I just used theirs. I created a configuration to define the display size to the the Xorg server. A basic configuration to define display size can be done like this:

cat /usr/share/X11/xorg.conf.d/90-monitor-disp-size.conf
Section "Monitor"
  Identifier "<default monitor>"
  DisplaySize 477 268
EndSection

Arch Linux and most distros use /etc/X11/xorg.conf.d/. However this won’t work on the external monitor. So I expanded on it (more than it probably needed to be) by defining both monitors and related sections:

Section "Monitor"
  Identifier    "Internal - Pavilion Laptop"
  DisplaySize    304.5 228.6
EndSection

Section "Monitor"
  Identifier    "External - Samsung Syncmaster SA350"
  VendorName    "Samsung"
  ModelName     "SA300/SA350"
  DisplaySize    476 267.7
EndSection

Section "Device"
  Identifier    "ATI Radeon Mobility IGP 330M"
  Option        "Monitor-VGA-0"  "External - Samsung Syncmaster SA350"
  Option        "Monitor-LVDS"   "Internal - Pavilion Laptop"
EndSection

Section "Screen"
  Identifier    "Default Screen"
  Monitor       "Internal - Pavilion Laptop"
EndSection

Section "ServerLayout"
  Identifier    "Default Layout"
  Screen        "Default Screen"
EndSection

I added VendorName and ModelName but I’m not sure they uniquely define the monitor so that the Xorg server acknowledges them. The VendorName I believe is just for reference, ModelName can usually be discovered by doing:

grep "Monitor name" /var/log/Xorg.0.log

Monitor-VGA-0 and Monitor-LVDS define the ports and hence by reference should uniquely define the monitor (xrandr -q shows them and both are found in the Xorg log).

After a bit of research I discovered that there is a good amount of history concerning the Xorg server having a bit of trouble in not being able to correctly discover the display size. I believe this may be related to some drivers. I’ve been told the open-source ATI driver have had problems and read in some other places of other people who have had similar issues. Defining the display size in the configuration and telling the Xorg server not to use the auto-detected value can be done by adding this to the Devices section (for Nvidia drivers use: Option "UseEDID" "FALSE"):

 Option        "NoDDC"

Unfortunately, this didn’t work either and left me completely at a loss. Unsure how to go further to define display size in the the Xorg server configuration I decided to define it through xrandr.

xrandr has an option to define the display size with the --fbmm option:

xrandr --output VGA-0 --auto -fbmm 476x267.7

--auto uses the default/preferred mode of the monitor.

Missed Touchpad Button Clicks

I had gotten this laptop as a gift/hand-me-down from someone else. Since the first thing I did was install Linux, I hadn’t thought otherwise that the buttons hadn’t been treated to well: left-click was very stubborn, often missing on some very obvious pushes. The action/response of the button resembled a sticky button. Because right-click was better, I created a script that would switch/toggle left and right click. I toggled it twice to test it (so that it reverted back to the original) when and found that left-click was working normally. Not sure why this fixed the problem and have yet to see another problem like this but I’m glad it’s good again. I created a script to quickly do this then added .desktop file to have it load on Login. The script:

Then I created a desktop file touchpad-button-fix.desktop in ~/.config/autostart to start it on Login:

Additional, the touchpad button may revert to it’s original behavior after resuming from sleep. To run the script upon resume it will need to be defined to pm-utils. Put this in /etc/pm/sleep.d/90_touchpad-button-fix:

Then make them executable:

sudo chmod +x ~/.config/autostart/touchpad-button-fix.desktop
sudo chmod +x /etc/pm/sleep.d/90_touchpad-button-fix

Setting Up a Scripting Environment

When first starting learning Linux, I didn’t realize lot of it lies beneath the surface. Linux still holds on to it’s developmental roots and a good deal of it’s power can be found directly from the command line. Windows doesn’t have this type of functionality, and though Mac OS X has some of it few people know about it. If needing to do powerful or automated commands with Linux (whether it be switch mouse buttons, or launch multiple programs at once), many times I can turn to the command line and write a bash script for it. The command line can be very powerful: there are few things that can only be done only from a window, and many more from the command line that can’t be done in a window.

Setting up a scripting environment means creating a place to store the scripts, easily getting to them, and executing them like a regular command.

Directory Setup

First thing I do is set up a directory to place the scripts in. This directory is usually best in the home folder and is preferably invisible as it’s not necessary to see it all the time. This may sound inconvenient at first but since commands will be run from the terminal it is quickly gotten used to. I like to name the directory ~/.scripts, others follow Linux filesystem convention and use ~/.local/bin (dot files are hidden files and are not shown unless explicitly stated):

mkdir ~/.scripts

The tilda character (~) signifies that the directory is the home directory and is used as a shortcut because it is quicker than typing /home/user. To quickly switch to that directory, I create a shortcut in the bash configuration file. Shortcuts can be defined in the bash configuration file using aliases. The bash configuration file is called ~/.bashrc. Adding the shortcut:

alias cds="cd ~/.scripts"

cds tells me to: change to the directory of scripts. After I save it, I re-source the bash configuration file to reload the new settings.

source ~/.bashrc

Now typing the shortcut cds will change to the script directory.

Run Scripts Just Like Regular Commands

I create new scripts here or put those I find here. Creating a script is outside this post but once they are here they will need to be executable:

chmod +x script-name

To be able to run the script like a regular command, the bash shell will need to be let known of the new executable path (~/.scripts). Anytime a command is run in bash, it looks for programs or scripts that are in the path directive. Currently known paths can be discovered by:

echo $PATH

To add the script directory to the known paths, it needs to be defined in the ~/.bashrc file. The bash configuration file may already have some paths defined in the export PATH... line. If it does, the script directory can be added to the line. If it doesn’t, I add both the script directory and the current paths ($PATH) to be sure the new path(s) don’t override the old:

export PATH="~/.scripts:$PATH"

Different paths are separated by a colon (:) and as many can be added as needed. Saving and sourcing ~/.bashrc will have the new directory(ies) be recognized by the bash shell.

Related

  • If you like to learn more about copying scripts (or text) from a window and pasting it to a file from the command line, see Command Line to Clipboard.

For the truly paranoid

HeaderI’ve been reinstalling my system as of late (been way too along a comin’) and I realized that I hadn’t set up a firewall yet. This, in turn, had me think how many ports were open. I was up too late and probably had too many cokes by then. I had given myself a dead simple root password so that I could finish the install and began getting that tightening, turning, wretching in the belly feeling. I couldn’t help thinking that, “This could be the time that some random joe comes along and finds a nice open gate”. Doesn’t make much sense now, but decided then to build a script that toggles a 20 character random password to relieved my paranoia. Here it is for anyone who can find use of it. Oh, and I did get my install done.

#!/bin/bash
# randompass - toggle between random and known passwords for users

# User passwords to protect
users=(root todd akau)

# Program name from it's filename
prog=${0##*/}

# Text color variables
txtund=$(tput sgr 0 1)          # Underline
txtbld=$(tput bold)             # Bold
bldred=${txtbld}$(tput setaf 1) #  red
bldblu=${txtbld}$(tput setaf 4) #  blue
bldwht=${txtbld}$(tput setaf 7) #  white
txtrst=$(tput sgr0)             # Reset
info=${bldwht}*${txtrst}        #
pass=${bldblu}*${txtrst}
warn=${bldred}!${txtrst}

# Check if users exist, if they don't remove from the users array
list="${users[@]/%/|}"    # Puts array to list, add pipe after each user
users=($(grep -Eo "^(${list// })\>" /etc/shadow)) # strip spaces, end of word

# Password generation
passgen=$(< /dev/urandom tr -dc A-Za-z0-9/.$ | head -c20 | xargs | cat)

# Variables for current passwords
for user in ${users[@]}; do
  eval "curpw$user=\$(grep \$user /etc/shadow | awk -F : '{print \$2}')"
done

# Save original passwords (first run)
for save in ${users[@]}; do
  if [ ! -f /root/pass$save ]; then
    grep $save /etc/shadow | awk -F : '{ print $2 }' > /root/pass$save
    echo "$pass Saved ${txtund}$save${txtrst} password"
  fi
done

case $1 in
  h ) echo " $prog <*u>- toggle random and known passwords. u - update known"
      ;;
  u ) echo "$warn Be sure no random passwords are set before updating passwords!"
      echo -n "Update known passwords file(s)? "
      read update
      if [[ $update == [Yy] ]]; then
        for known in ${users[@]}; do
          grep $known /etc/shadow | awk -F : '{ print $2 }' > /root/pass$known
          echo "$pass Updated ${txtund}$known${txtrst} password"
        done
        else
        echo " Passwords not updated"
        exit
      fi
      ;;
  * ) if [[ "$curpwroot" == "$(cat /root/passroot)" ]]; then
        for u in ${users[@]}; do
          usermod -p $passgen $u
          echo "$pass Generated password for ${txtund}$u${txtrst}."
        done
        else
        for u in ${users[@]}; do
          usermod -p $(cat /root/pass$u) $u
          echo "$pass Restored password for ${txtund}$u${txtrst}."
        done
      fi
      ;;
esac

theatertime- hold power-saving to get through a flick

Getting down to watching you favorite movie on your computer? Start the movie, sit down, grab your snack and ten or so minutes later the screen goes blank. This happens in Linux because the desktop has built-in defaults for display power management (DPMS) and screensaving. Timeout settings can vary from distribution to distribution but they all got them. Here’s a basic script that can toggle DPMS and screensaving on and off.

Xorg Server Settings

You can set the values of blank, standby, suspend, and off in the the xorg server configuration file. The defaults are: 15, 20, 30, and 40 minutes. Personally I like to set these to better match how I use my computer:

Section "Monitor"
  Identifier  "Monitor0"
  Option      "DPMS"    "true"  # display power management on (true/false)
EndSection

Section "ServerFlags"
  Option "BlankTime"    "13"    # LED still on, no + (0 disables)
  Option "StandbyTime"  "15"    # turns off LED
  Option "SuspendTime"  "0"     # turns off LED, and most power
  Option "OffTime"      "50"    # turns off all power
EndSection

BlankTime is just a cheap screensaver and only real use for me is to tell me that I forgot to disable dpms while watching a movie. Doing this saves me a few seconds that StandbyTime requires to turn on the display again. SuspendTime and StandbyTime are nearly the same thing so I don’t bother setting SuspendTime.

Movietime

Here’s movietime. Movietime should work with just about any type of desktop environment (at least any system with dbus installed which really all of them do). If you aren’t familiar with having your own scripts and how to run them, take a look at this page).

#!/bin/bash
# movietime - disables power savings to watch movies.

# Movietime options
#  Resume time - resume normal display pm and suspend after set time.
# 0 = disabled, time in minutes
resumetime=0
if [ $resumetime = 0 ]; then 
  resumetime=1440 # Re-enable resume after a full day
fi

# Check that values for 'resumetime' are numbers
if [ $(echo $resumetime | sed 's/^[-+0-9][0-9]*//' | wc -c) != 1 ]; then
  echo "$warn variable 'resumetime' is not a number.  Exiting."
  exit
fi

# Name of suspend script
tmploc="/tmp"
suspinhscript="$tmploc"/"movietime-suspend-inhibit"

# Program name from it's filename.
prog=${0##*/}

# Text color variables
txtund=$(tput sgr 0 1)          # Underline
txtbld=$(tput bold)             # Bold
bldblu=${txtbld}$(tput setaf 4) #  blue
bldwht=${txtbld}$(tput setaf 7) #  white
bldred=${txtbld}$(tput setaf 1) #  red
txtrst=$(tput sgr0)             # Reset
info=${bldwht}*${txtrst}        # Feedback
pass=${bldblu}*${txtrst}
warn=${bldred}*${txtrst}

# Check that Xorg server is running
if [[ -z $(ps aux | grep /usr/bin/X) ]]; then
  echo "$warn The Xorg server is not running."
  exit
fi

# Check if user is regular user
if [ $(whoami) == "root" ]; then
  echo "$warn You are the root user, must be a regular user."
  exit
fi

# Current DPMS times (in minutes)
dispdpms=$(xset -q | grep "DPMS is" | awk '{ printf $3 }') # Enab. or Disb.
dispstand=$(xset -q | grep "^  Standby: " | awk '{ printf $2/60 }')
dispsusp=$(xset -q | grep "^  Standby: " | awk '{ printf $4/60 }')
dispoff=$(xset -q | grep "^  Standby: " | awk '{ printf $6/60 }')
dispblank=$(xset -q | grep "^  timeout:  " | awk '{ printf $2/60 }')

# Resume time in hours
resumetimehr=$(echo "scale=1;${resumetime}/60" | bc)

# Display help
case $1 in
  -h | --help | h | help )
    # Help message.
    echo
    echo "  $prog disables screen blanking and screensaver to allow viewing a video.  Running the program again will enable them.  If the 'resumetime' variable is set after that time $prog will resume normal powersaving values." | fmt -c -w 76
    echo

    # Display current values of power management and movietime.
    suspinhtest=$(ps aux | grep -v grep | grep $suspinhscript)
    suspinhval=$([ -n "$suspinhtest" ] && echo "Disabled" || echo "Desktop settings")
    
    # DPMS disabled information
    echo "   ${txtbld}Current settings ${txtrst}(in minutes, 0 = disabled):"
    if [[ "$dispdpms" == "Disabled" ]]; then
      echo "   DPMS:         $dispdpms"
      echo "   Suspend:      $suspinhval"
    fi

    # DPMS enabled information
    if [[ "$dispdpms" == "Enabled" ]]; then
      echo "   DPMS:         $dispdpms"
      echo "   DPMS times:   Blank: ${dispblank}; Standby: ${dispstand}; Suspend: ${dispsusp}; Offtime: ${dispoff}"
      echo "   Suspend:      $suspinhval"
    fi
    echo
    echo "   ${txtbld}$prog settings${txtrst}:"
    echo "   Resume after: $resumetimehr hours"
    echo
    exit
    ;;
  [a-g,i-z,A-G,I-Z,0-9,-]* )
    echo " Use '-h' for help"
    exit
    ;;
esac

# Suspend inhibit script (must be run as seperate process)
suspinhibit () {
    echo '#!/bin/bash
    for time in $(seq 1 '$resumetime'); do
    # Simulate user activity every minute
    dbus-send --print-reply --type=method_call --dest=org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SimulateUserActivity
    sleep 60
    done'
}

# Toggle powersaving
if [[ "$dispdpms" == "Enabled" ]] && [ -z "$suspinhtest" ]; then
  # Disable blanking, screen power saving
  xset s off; xset -dpms
  # Create script in tmp
  suspinhibit > "$suspinhscript"
  # Make script executable
  chmod u+x "$suspinhscript"
  # Run script
  nohup "$suspinhscript" &> /dev/null &
  echo "$pass $prog started, powersaving disabled."
else
  # Enable blanking, screen power saving
  xset s on; xset +dpms
  # Kill script
  if [ -n $suspinhtest ]; then
    echo "$info $prog stopped, powersaving enabled."
    kill -s 9 $(pgrep movietime-susp) &> /dev/null
  fi
fi

Turn off all cellphones and enjoy the show!

Week of bash scripts – rps and commentstrip

These two scripts will respectively: find if a program is running, and strip-comments from text files. The first is useful if you need to see if the program is running or if you need to kill the process with it’s id, comment strip is a good tool to use if posting configurations on forums as often developers or advanced users already know what the settings actually do.

rps

aspire ~/.scripts:
rps geany
todd      1827  0.1  0.3 184576 28616 ?        S    May31   1:05 geany

commentstrip

Commentstrip will display the output to the terminal. If you got xclip installed the ‘c’ option can be used to copy the output to the clipboard.

The final day of week of bash scripts… phew! I’d like to thank everyone that posted comments, and to those that stopped by this week.

Week of bash scripts – grok and cdf

These two scripts are two different find commands. The first (grok) will list all files in a directory recursively that contain a matched string; the second will locate a file/folder and the change to it’s directory. Neither of these are mine (though slightly edited), I’ve gotten them from the Arch forums where they have a great thread called Post your handy self made command line utilities.

Grok

This one is by rebugger and I call it grok. Syntax is:

grok <string> <*location>

If no location is given it uses the current directory.

aspire ~:
grok 127.0.0.1 /etc/
 Searching...
/etc/dnsmasq.conf
/etc/dnsmasq.conf.pacorig
/etc/hosts
/etc/NetworkManager/dispatcher.d/localhost-prepend
/etc/ntp.conf
/etc/resolv.conf
/etc/security/access.conf
/etc/xinetd.d/servers
/etc/xinetd.d/services

cdl

This one is by segoe that uses locate to find a file and that cd’s to the first match found.

aspire ~/.scripts:
cdl demo/PKG
aspire ~/.arch/pkgbuilds/amnesia-demo:

This one put in your ~/.bashrc:

cdf () { cd "$(dirname "$(locate -i "$*" | head -n 1)")" ; } # locate then cd

Restore settings of Firefox on trouble

Update: 09-29-11 – Using script to automate process, see end of post.

When people have a issue with Firefox I’ve seen many people will resort to deleting their old profile (or folder) and creating a new one. This works but doing this will get rid of any passwords, history, bookmarks… therein. Having used Firefox quite a bit creating a new profile from time to time is a good idea anyhow as cruft, bad extensions, … can slow down browsing.

Manually

Copying the Firefox configs can be done by:

cd ~/.mozilla/firefox/

Backup the old profile and profile list:

mv xxxxxxxx.default{,.bck}
mv profiles.ini{,.bck}

Create a new profile:

firefox -CreateProfile <profilename>

This command will return the name of the new folder. Copy the basic settings to the new profile:

cd *.default.bck
cp places.sqlite key3.db cookies.sqlite mimeTypes.rdf formhistory.sqlite signons.sqlite permissions.sqlite webappsstore.sqlite persdict.dat content-prefs.sqlite ../*.<profilename>

This will transfer the bookmarks, browsing history, form entries, passwords, personal dictonary changes, and page zooms. There might be a couple other things wanted to add (possibly your firefox preferences), take a look at Transferring data to a new profile for more information.

Color Output on Bash Scripts (Advanced)

I talked in a previous post about basic bash script colored output using the tput command. The tput command works for basic coloring (providing seven colors to choose from) but ANSI also provides a 256 color palette.

Note: Not all terminals support ANSI, but most do.

ANSI color coding is in this form:

\033[01;38;5;160m

The ANSI sequence: {ESC}[{attr};{bg};{256colors};{fg}m

{ESC} or \033 represents the ANSI escape-sequence. {attr} represents the outputs attributes (properties such as blinking and bold text), {fg} is the foreground color, {bg} is the background color, m means the sequence ends.

Note: The escape-sequence \033 works fine but at times you might have to use \e.

An example:

echo -e "My favorite color is \033[38;5;148mYellow-Green\033[39m"

The variable -e is required because echo doesn’t normally interpret backslashes and 033[39m tells bash to end the seqeunce. The 38 Value will use no background color. Notice too that I omitted the attribution value which if isn’t used will use the default (regular text) value.

To get color values a good program is colortest.

colortest -w

Colortest will show the ANSI color value to the corresponding hex value. Then just insert the ANSI value into the either the foreground or background value.
There’s also a program called conv-rgb2xterm that a hex value can be put in and it will give and ANSI sequence for the foreground color.

References