| #!/bin/bash |
| # |
| # Preprocessor for 'less'. Used when this environment variable is set: |
| # LESSOPEN="|lesspipe %s" |
| |
| # TODO: handle compressed files better |
| |
| [[ -n ${LESSDEBUG} ]] && set -x |
| |
| trap 'exit 0' PIPE |
| |
| guesscompress() { |
| case "$1" in |
| *.gz|*.z) echo "gunzip -c" ;; |
| *.bz2|*.bz) echo "bunzip2 -c" ;; |
| *.lz) echo "lzip -dc" ;; |
| *.lzma) echo "unlzma -c" ;; |
| *.lzo) echo "lzop -dc" ;; |
| *.xz) echo "xzdec" ;; |
| *) echo "cat" ;; |
| esac |
| } |
| |
| lesspipe_file() { |
| local out=$(file -L -- "$1") |
| local suffix |
| case ${out} in |
| *" 7-zip archive"*) suffix="7z";; |
| *" ar archive"*) suffix="a";; |
| *" CAB-Installer"*) suffix="cab";; |
| *" cpio archive"*) suffix="cpio";; |
| *" ELF "*) suffix="elf";; |
| *" LHa"*archive*) suffix="lha";; |
| *" troff "*) suffix="man";; |
| *" script text"*) suffix="sh";; |
| *" shared object"*) suffix="so";; |
| *" tar archive"*) suffix="tar";; |
| *" Zip archive"*) suffix="zip";; |
| *": data") hexdump -C -- "$1"; return 0;; |
| *) return 1;; |
| esac |
| lesspipe "$1" ".${suffix}" |
| return 0 |
| } |
| |
| lesspipe() { |
| local match=$2 |
| [[ -z ${match} ]] && match=$1 |
| |
| local DECOMPRESSOR=$(guesscompress "${match}") |
| |
| # User filters |
| if [[ -x ~/.lessfilter ]] ; then |
| ~/.lessfilter "$1" && exit 0 |
| fi |
| |
| local ignore |
| for ignore in ${LESSIGNORE} ; do |
| [[ ${match} == *.${ignore} ]] && exit 0 |
| done |
| |
| case "${match}" in |
| |
| ### Doc files ### |
| *.[0-9n]|*.man|\ |
| *.[0-9n].bz2|*.man.bz2|\ |
| *.[0-9n].gz|*.man.gz|\ |
| *.[0-9n].lzma|*.man.lzma|\ |
| *.[0-9n].xz|*.man.xz|\ |
| *.[0-9][a-z].gz|*.[0-9][a-z].gz) |
| local out=$(${DECOMPRESSOR} -- "$1" | file -) |
| case ${out} in |
| *troff*) |
| # Need to make sure we pass path to man or it will try |
| # to locate "$1" in the man search paths |
| if [[ $1 == /* ]] ; then |
| man -- "$1" |
| else |
| man -- "./$1" |
| fi |
| ;; |
| *text*) |
| ${DECOMPRESSOR} -- "$1" |
| ;; |
| *) |
| # We could have matched a library (libc.so.6), so let |
| # `file` figure out what the hell this thing is |
| lesspipe_file "$1" |
| ;; |
| esac |
| ;; |
| *.dvi) dvi2tty "$1" ;; |
| *.ps|*.pdf) ps2ascii "$1" || pstotext "$1" || pdftotext "$1" ;; |
| *.doc) antiword "$1" || catdoc "$1" ;; |
| *.rtf) unrtf --nopict --text "$1" ;; |
| *.conf|*.txt|*.log) ;; # force less to work on these directly #150256 |
| |
| ### URLs ### |
| ftp://*|http://*|*.htm|*.html) |
| for b in links2 links lynx ; do |
| ${b} -dump "$1" && exit 0 |
| done |
| html2text -style pretty "$1" |
| ;; |
| |
| ### Tar files ### |
| *.tar|\ |
| *.tar.bz2|*.tar.bz|*.tar.gz|*.tar.z|\ |
| *.tar.lz|*.tar.tlz|\ |
| *.tar.lzma|*.tar.xz) |
| ${DECOMPRESSOR} -- "$1" | tar tvvf -;; |
| *.tbz2|*.tbz|*.tgz|*.tlz|*.txz) |
| lesspipe "$1" "$1".tar.${1##*.t} ;; |
| |
| ### Misc archives ### |
| *.bz2|\ |
| *.gz|*.z|\ |
| *.lz|\ |
| *.lzma|*.xz) ${DECOMPRESSOR} -- "$1" ;; |
| *.rpm) rpm -qpivl --changelog -- "$1" ;; |
| *.cpi|*.cpio) cpio -itv < "$1" ;; |
| *.ace) unace l "$1" ;; |
| *.arc) arc v "$1" ;; |
| *.arj) unarj l -- "$1" ;; |
| *.cab) cabextract -l -- "$1" ;; |
| *.lha|*.lzh) lha v "$1" ;; |
| *.zoo) zoo -list "$1" || unzoo -l "$1" ;; |
| *.7z|*.exe) 7z l -- "$1" || 7za l -- "$1" || 7zr l -- "$1" ;; |
| *.a) ar tv "$1" ;; |
| *.elf) readelf -a -W -- "$1" ;; |
| *.so) readelf -h -d -s -W -- "$1" ;; |
| *.mo|*.gmo) msgunfmt -- "$1" ;; |
| |
| *.rar|.r[0-9][0-9]) unrar l -- "$1" ;; |
| |
| *.jar|*.war|*.ear|*.xpi|*.zip) |
| unzip -v "$1" || miniunzip -l "$1" || miniunz -l "$1" || zipinfo -v "$1" |
| ;; |
| |
| *.deb|*.udeb) |
| if type -P dpkg > /dev/null ; then |
| dpkg --info "$1" |
| dpkg --contents "$1" |
| else |
| ar tv "$1" |
| ar p "$1" data.tar.gz | tar tzvvf - |
| fi |
| ;; |
| |
| ### Filesystems ### |
| *.squashfs) unsquashfs -s "$1" && unsquashfs -ll "$1" ;; |
| |
| ### Media ### |
| *.bmp|*.gif|*.jpeg|*.jpg|*.ico|*.pcd|*.pcx|*.png|*.ppm|*.tga|*.tiff|*.tif|*.webp) |
| identify "$1" || file -L -- "$1" |
| ;; |
| *.asf|*.avi|*.mov|*.mp4|*.mpeg|*.mpg|*.qt|*.ram|*.rm|*.webm|*.wmv) |
| midentify "$1" || file -L -- "$1" |
| ;; |
| *.mp3) mp3info "$1" || id3info "$1" ;; |
| *.ogg) ogginfo "$1" ;; |
| *.flac) metaflac --list "$1" ;; |
| *.torrent) torrentinfo "$1" || torrentinfo-console "$1" || ctorrent -x "$1" ;; |
| *.bin|*.cue|*.raw) |
| # not all .bin/.raw files are cd images #285507 |
| # fall back to lesspipe_file if .cue doesn't exist, or if |
| # cd-info failed to parse things sanely |
| [[ -e ${1%.*}.cue ]] \ |
| && cd-info --no-header --no-device-info "$1" \ |
| || lesspipe_file "$1" |
| ;; |
| *.iso) |
| iso_info=$(isoinfo -d -i "$1") |
| echo "${iso_info}" |
| # Joliet output overrides Rock Ridge, so prefer the better Rock |
| case ${iso_info} in |
| *$'\n'"Rock Ridge"*) iso_opts="-R";; |
| *$'\n'"Joliet"*) iso_opts="-J";; |
| *) iso_opts="";; |
| esac |
| isoinfo -l ${iso_opts} -i "$1" |
| ;; |
| |
| ### Encryption stuff ### |
| *.crl) openssl crl -hash -text -noout -in "$1" ;; |
| *.csr) openssl req -text -noout -in "$1" ;; |
| *.crt|*.pem) openssl x509 -hash -text -noout -in "$1" ;; |
| |
| # May not be such a good idea :) |
| # ### Device nodes ### |
| # /dev/[hs]d[a-z]*) |
| # fdisk -l "${1:0:8}" |
| # [[ $1 == *hd* ]] && hdparm -I "${1:0:8}" |
| # ;; |
| |
| ### Everything else ### |
| *) |
| case $(( recur++ )) in |
| # Maybe we didn't match due to case issues ... |
| 0) lesspipe "$1" "$(echo $1 | LC_ALL=C tr '[:upper:]' '[:lower:]')" ;; |
| |
| # Maybe we didn't match because the file is named weird ... |
| 1) lesspipe_file "$1" ;; |
| esac |
| |
| # So no matches from above ... finally fall back to an external |
| # coloring package. No matching here so we don't have to worry |
| # about keeping in sync with random packages. Any coloring tool |
| # you use should not output errors about unsupported files to |
| # stdout. If it does, it's your problem. |
| |
| # Allow people to flip color off if they dont want it |
| case ${LESSCOLOR} in |
| always) LESSCOLOR=2;; |
| [yY][eE][sS]|[yY]|1|true) LESSCOLOR=1;; |
| [nN][oO]|[nN]|0|false) LESSCOLOR=0;; |
| *) LESSCOLOR=0;; # default to no color #188835 |
| esac |
| if [[ ${LESSCOLOR} != "0" ]] && [[ -n ${LESSCOLORIZER=code2color} ]] ; then |
| # 2: Only colorize if user forces it ... |
| # 1: ... or we know less will handle raw codes -- this will |
| # not detect -seiRM, so set LESSCOLORIZER yourself |
| if [[ ${LESSCOLOR} == "2" ]] || [[ " ${LESS} " == *" -"[rR]" "* ]] ; then |
| LESSQUIET=true ${LESSCOLORIZER} "$1" |
| fi |
| fi |
| |
| # Nothing left to do but let less deal |
| exit 0 |
| ;; |
| esac |
| } |
| |
| if [[ -z $1 ]] ; then |
| echo "Usage: lesspipe <file>" |
| elif [[ $1 == "-V" || $1 == "--version" ]] ; then |
| Id="cvsid" |
| cat <<-EOF |
| $Id: lesspipe.sh,v 1.53 2013/08/06 21:35:30 vapier Exp $ |
| Copyright 2001-2013 Gentoo Foundation |
| Mike Frysinger <vapier@gentoo.org> |
| (with plenty of ideas stolen from other projects/distros) |
| |
| |
| EOF |
| less -V |
| elif [[ $1 == "-h" || $1 == "--help" ]] ; then |
| cat <<-EOF |
| lesspipe: preprocess files before sending them to less |
| |
| Usage: lesspipe <file> |
| |
| lesspipe specific settings: |
| LESSCOLOR env - toggle colorizing of output (no/yes/always) |
| LESSCOLORIZER env - program used to colorize output (default: code2color) |
| LESSIGNORE - list of extensions to ignore (don't do anything fancy) |
| |
| You can create per-user filters as well by creating the executable file: |
| ~/.lessfilter |
| One argument is passed to it: the file to display. |
| |
| To use lesspipe, simply add to your environment: |
| export LESSOPEN="|lesspipe %s" |
| |
| Run 'less --help' or 'man less' for more info |
| EOF |
| elif [[ -d $1 ]] ; then |
| ls -alF -- "$1" |
| else |
| recur=0 |
| [[ -n ${LESSDEBUG} ]] \ |
| && lesspipe "$1" \ |
| || lesspipe "$1" 2> /dev/null |
| fi |