A more useful ls


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting A more useful ls
# 1  
Old 08-25-2008
MySQL A more useful ls

Tired of typing "ls -l | less" all the freakin' time? Drop this in your .profile (better yet, put it in a separate file and source it from your .profile). Though it is somewhat BASH specific, I'll be happy to port it for other SH**heads. It defaults to usage with GNU color ls and with less, but complete customization is possible through $LSX, $LS_OPTIONS, $PAGER and $PAGER_OPTIONS environment variables.

Code:
#!/bin/bash
#
# Usage:
#   . lsless.sh
# Command-line:
#   ls | ${PAGER}
#
# Pipe your ls command through your PAGER. Options are passed to ls.
# If your PAGER is smart enough, only page if the output is more than
# one screenful.
#
# ls is cool, but if the listing goes beyond a page, it's a pain in the ass.
# Most folks use their terminal's scrollback, or revert to using ls -C or
# Some get smart and alias a command to pipe ls through their pager.
# This script sets it up so you don't have to worry about it at all.
#
# Features:
# o  If standard out is a pipeline, normal behavior ensews. (requires tty -s to work).
# o  ls will use the options and filenames specified on the command line!
# o  If no options on the command-line are specified,
#       ls use the options defined in $LS_OPTIONS
# o  LS_OPTIONS defaults are set herein (differntly for GNU vs *NIX)
#      -F : append classifier symbols after each file
#      -l : long listing
#      -h : "human readable" ls -- filesizes in K, M, G, etc.
#      -T 0 : Don't produce tabs to the terminal (screws up less sometimes)
#
# o  The pager will use the $PAGER_OPTIONS environment variable.
#    The Defaults used here:
# -  less (-F) or more (-e) will exit immediately if the listing is < 1 page
# -  less (-R)/more will display the GNU-ls colors (unset LS_COLORS to turn off)
# -  less (-e) will exit without needing to hit 'q' at the end of the listing
# -  less (-J) uses the leftmost column for a status in searching
# -  less (-X) don't clear the screen  (usually -- terminal dependent)
# -  less (-S) chop long lines instead of folding (not used in mine)
# -  less (-~) eof lines are displayed as blank lines instead of ~'s
#
#
# Notes:
#   If your pager is not less (ie, it is "more" or "pg") and you don't like
#   its behavior here, just don't use this file. The whole point is to pipe
#   ls through the pager

# If we have a color/gnu ls, then use it with some default options
if test -z "$LSX" ; then
  for _LSX in `type -ap gls` `type -ap ls` ; do
    if $_LSX --version 2>/dev/null | grep '^Copyright.*Free Software Foundation' ; then
      LSX=`type -p $_LSX`;
      LS_OPTIONS="-Flh -T 0";
      break
    fi >&/dev/null
  done
fi

# user defined colors:
if test -r "$HOME/.dir_colors" ; then
  eval `dircolors $HOME/.dir_colors`
elif test -r "/etc/DIR_COLORS" ; then
  eval `dircolors /etc/DIR_COLORS`
fi

# Clean out any system-defined ls commands or hacks so we can define our own
if alias ls &>/dev/null ; then
  unalias ls
fi
if declare -f ls &>/dev/null ; then
  unset -f ls
fi

# Non-GNU ls -- use highly standard options
if test -z "$LSX" ; then
  LSX="command ls"
  LS_OPTIONS="-Fxl"
fi

# Make sure we have the pager we want
if test -z "$PAGER"; then
  if less </dev/null &>/dev/null ; then
    PAGER=less
    PAGER_OPTIONS="${PAGER_OPTIONS:-"-FeRJgX~ --"}"
  elif more -e </dev/null &>/dev/null ; then
    PAGER=more
    # The option is like less's -F option
    PAGER_OPTIONS="-e"
  else
    PAGER=more
    PAGER_OPTIONS=""
  fi
fi

_debug_check() {
  if [ "$1" = "stop" -o "_$_debugging" = "_on" ]; then
    unset _debugging
    set +vx
  elif [ -z "$1" -o "$1" = "start" ]; then
    test -n "$DEBUG_RC" && test "$DEBUG_RC" -gt 1 && set -vx
    _debugging="on"
  fi
}

# Redefine ls to pipe through our pager
#   + output debugging info if the var DEBUG_RC is set and greater than 1
#   + separate opts from filenames (TwI take parameters, thus shift 2)
#   + if LS_COLORS is set, force color output
#   + also send errors (file not found) to pager
function ls() {
  _debug_check start

  local opts=""
  while [ -n "$1" ]; do
    case "$1" in
    --)     break; ;;
    -[TwI]) opts="$opts $1 $2"; shift 2; ;;
    -*)     opts="$opts $1"; shift; ;;
    *)      break; ;;
    esac
  done

  # if we are being piped to another command, use the system standard
  /usr/bin/tty -s <&1 || exec $LSX ${opts:-$LS_OPTIONS} "$@"

  if set -o |grep  '^pipefail[   ]*off$' &>/dev/null ; then
    set -o pipefail
    local pipefail_restore=1
  fi

  $LSX ${opts:-$LS_OPTIONS} ${LS_COLORS:+"--color=always"} "$@" 2>&1 \
  | ${PAGER} ${PAGER_OPTIONS} ;
  local ret=$?

  # restore pipefail to previous state
  test -z $pipefail_restore || set +o pipefail

  # turn off debugging
  _debug_check stop

  # return code valid ONLY if pipefail is available
  return $ret
}
#export -f ls
# ^^--- exporting ls causes problems when using scripts which depend on ls,
#       such as "configure" :( That's why this was moved to bashrc directory
export LSX LS_OPTIONS PAGER PAGER_OPTIONS
#
# Version 1.1
#
# copyright 2006,2008 by Otheus at gmail.com
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
#


Last edited by otheus; 11-07-2008 at 09:10 AM.. Reason: Now at version 1.1. Bug fixes when called as part of a pipeline.
Login or Register to Ask a Question

Previous Thread | Next Thread
Login or Register to Ask a Question