¿Qué personalizaciones ha realizado en su perfil de shell para aumentar la productividad?

25

Sé que algunas personas tienen algunos scripts de inicio y otras personalizan el mensaje. Un desarrollador usa alias cortos para la ruta larga que visita a menudo y los comandos frecuentes que ejecuta.

¿Cuáles son todas las personalizaciones efectivas que ha realizado en su perfil UNIX para aumentar la productividad y la facilidad de uso?

San
fuente
debe ser CW, no se puede responder objetivamente.
akira
Estoy de acuerdo. Sin embargo, no había opción para CW. :-(
San
@akira @Michael Me enfrento a esta situación a menudo. Sería genial si los moderadores pudieran editar / publicar / redireccionar la pregunta. Porque el comentario que dejas no ayuda mucho al usuario para lograr lo que realmente quiere. Sin ofender, solo una sugerencia. Espero que entiendas.
San
Si desea hacer una pregunta wiki comunitaria, márquela para la atención del moderador. Consulte las preguntas frecuentes de la wiki de la comunidad .
Gilles 'SO- deja de ser malvado'

Respuestas:

11

.vimrc

guarde el archivo con permisos de root escribiendo w!!:

cmap w!! w !sudo tee % > /dev/null


.bashrc

No se moleste con dispositivos o archivos binarios cuando greping:

alias grep='grep --color=auto --binary-files=without-match --devices=skip'


Comparta código en la web (como pastebin, pero más simple) por cat 1337.sh | webshare

alias webshare='curl -F "sprunge=<-" http://sprunge.us | xclip'

Devuelve una url corta en tu portapapeles; puede agregar ?whatever-langa la URL devuelta para resaltar su sintaxis y numerar las líneas.


.inputrc

Use el modo vi en todo lo que use la biblioteca readline (muchos programas):

set editing-mode vi
set keymap vi
Shawn J. Goff
fuente
Grandes consejos que nunca supe.
San
7

hacer un directorio y cd en un comando

La mayoría de las veces lo hago mkdir, mi siguiente comando es cd <that dir>.

Esto ahorra algo de tipeo:

# make a directory and cd to it
mcd()
{
    test -d "$1" || mkdir "$1" && cd "$1"
}

por ejemplo:

/home/mikel$ mcd somedir
/home/mikel/somedir$ 

Otra cosa que encuentro útil es una manera fácil de hacer un directorio desechable. por ejemplo, si estoy compilando un programa o incluso si intento reproducir un problema en este sitio. A veces me olvido de limpiar el directorio.

# make a temporary directory and cd to it
mtd()
{
    local dir
    dir=$(mktemp -d)
    if test -n "$dir"
    then
        if test -d "$dir"
        then
            echo "$dir"
            cd "$dir"
        else
            echo "mktemp directory $dir does not exist"
        fi
    else
        echo "mktemp didn't work"
    fi
}

mostrándolo funcionando:

/home/mikel$ mtd
/tmp/tmp.wsnZjJ2KN6
/tmp/tmp.wsnZjJ2KN6$ 

Confío en la limpieza del sistema /tmpdespués de un reinicio, pero sería posible mejorar esto, por ejemplo, hacer que elimine el directorio temporal después de salir del shell.

Mikel
fuente
Me encantó la opción mcd. Buena, gracias.
San
He estado usando mi versión mcddurante muchos años y voy a agregar algo como mtdpronto.
maaartinus
Yo definí mi mtd() { mcd $TMP/`date +%y%m%d-%H%M%S-%N`; }. Probablemente carece de portabilidad, pero es lo suficientemente bueno para mí.
maaartinus
4

Me gusta que mi indicador bash muestre el código de salida del comando anterior si no es cero. También me gusta que mi caparazón me anime cuando lo uso, así que agregué un poco de tontería:

smiley() {
    RC=$?
    [[ ${RC} == 0 ]] && echo ':)' || echo ":( ${RC}"
}

export PS1="\$(smiley) \h [\A] [\W] \$ "

así que cuando ejecuto comandos, recibo algunos comentarios visuales agradables:

:) mycomputer [23:03] [~] $ sh -c 'exit 0'
:) mycomputer [23:03] [~] $ sh -c 'exit 11'
:( 11 mycomputer [23:03] [~] $ 

editar : esto es algo que puse en mi ~ / .bashrc

revs jsbillings
fuente
Bastante interesante. Pero tengo una duda. ¿Dónde debería residir el código?
San
En .bashrcpresumiblemente.
Mikel
sí, eso está en mi ~ / .bashrc
jsbillings
Lo intentaré ..
San
4

arriba N

saltar N directorios hacia arriba en el árbol de directorios

En lugar de escribir

cd ../../../..

solo escribes

up 4

y un

cd -    

te traerá de vuelta

Ponga la función en su .bashrc para usarla.

# (c) 2007 stefan w. GPLv3          
function up {
ups=""
for i in $(seq 1 $1)
do
        ups=$ups"../"
done
cd $ups
}
usuario desconocido
fuente
Wow .. esa es una buena idea ..
San
2

.zshrc:

alias l='ls -CF'
alias ll='ls -ClhF'
alias la='ls -CaF'
alias lla='ls -CalhF'
alias l.='ls -CAF --ignore=\*'
alias ll.='ls -CAlhF --ignore=\*'
alias t='tree -C'

PS1=$'%{\e[0;33m%}%m %{\e[32;1m%}%~ %{\e[0;31m%}%#%{\e[m%} '

bindkey '^[[3~' delete-char

export GREP_OPTIONS="--color"

.xmodmaprc:

clear lock
keycode 9 = Caps_Lock ISO_Next_Group Caps_Lock ISO_Next_Group
keycode 66 = Escape NoSymbol Escape
add lock = Caps_Lock

(Teclas Swaps Escape y Caps Lock).

polemon
fuente
+1 para la reasignación de claves, mi Bloq Mayús está asignado a Retorno, ¿QUIÉN NECESITA BLOQUEO DE MAYÚSCULAS?
meneo
1
Soy un usuario de Vim. Es típico para los usuarios de Vim, asignar Escape a Caps Lock. Los usuarios de Emacs tienden a asignar Control a Bloqueo de mayúsculas.
polemon
1

Me equivoco con mi bashrc ya que uso mucho la terminal (me hace aprender rápido y aprender cosas interesantes para usar, así como herramientas interesantes). Usualmente defino muchas funciones en mi bashrc. Ejemplos:

Extraer archivos:

extract () {
libextract () {
if [ -f "$1" ] ; then
  case "$1" in
    *.tar.bz2) tar xjf "$1" ;;
    *.tar.gz)  tar xzf "$1" ;;
    *.bz2) bunzip2 "$1" ;;
    *.rar) rar x "$1" ;;
    *.gz) gunzip "$1" ;;
    *.tar) tar xf "$1" ;;
    *.tbz2) tar xjf "$1" ;;
    *.tgz) tar xzf "$1" ;;
    *.zip) unzip "$1" ;;
    *.Z) uncompress "$1" ;;
    *.7z) 7z x "$1" ;;
    *) echo "$1 ne moze biti raspakovan!" ;;
  esac
else
  echo "$1 nije validan fajl"
fi
}
 echo "Unesite putanju do direktorijuma u kome se nalaze arhive: " && read dir && dirprovera && cd $dir
  for f in *
    do
      mkdir ./$f-raspakovano && cd ./$f-raspakovano
      libextract ./../$f
      cd ./../
    done
  tipka
}

renombrar archivos y carpetas:

frename () {
if [ $# -gt 0 ]
then
 dir="$(echo $1)"
  dirprovera
  cd $dir
  for f in *
    do
      mv "$f" "`echo "$f" | tr -s " " "_" | tr "A-Z" "a-z"`" 2>/dev/null &
    done
  tipka
else
 echo "Upotreba: frename [direktorijum]" >&2
fi
}

y así para dividir archivos grandes en varios pequeños:

fsplit () {
if [ $# -gt 1 ]
then
 file="$(echo $1)"
 SIZE="$(echo $2)"
 PREFIX="$(echo $3)"
 if [ -z "$PREFIX" ]; then PREFIX="fsplit"; fi
  fileprovera
  split -d -a 3 -b $SIZE $file "$PREFIX-part-" || echo "Doslo je do greske!"
  tipka
else
 echo "Upotreba: fsplit [fajl] [velicina] [prefix]
Za velicinu se koriste m (MB), g (GB) ili k (KB) (15m, 650kb, 4.7g...)

Prefiks moze sadrzati brojeve, slova, i crtice (primer: moj_pre-fiks)
Ukoliko ne unesete prefiks isti ce biti dodeljen automatski u sledecem formatu:
  fsplit-part-XXX
gde XXX predstavlja broj dela fajla (001, 005, 189...)" >&2
fi
}

También edité muchos alias ya que encuentro que es mucho más fácil usar un comando con argumentos predeterminados en algunos casos (como en ls, grep y comandos pequeños) y luego escribir todo eso cada vez.

usuario2648
fuente
1

(Wiki de la comunidad, por lo que cada truco pertenece en una respuesta separada).

cierre de sesión seguro

Ctrl+ Des la forma más fácil de salir del shell, pero si todavía tiene trabajos en ejecución, saldrá feliz del shell de todos modos. Por defecto, esto significa que todos los programas que estaba ejecutando desde dentro de ese shell se eliminarán.

Algunos proyectiles solo le permitirán cerrar sesión después de presionar Ctrl+ Ddos veces, pero aún así es demasiado fácil hacerlo accidentalmente.

Entonces, en su lugar, agregue esto .bashrco el .zshrcarchivo de configuración que prefiera.

alias x='_exit'

# prevent running "exit" if the user is still running jobs in the background
# the user is expected to close the jobs or disown them
_exit()
{
    case $- in *m*)
        # this way works in bash and zsh
        jobs | wc -l | grep -q '^ *0 *$'
        if test $? -eq 0
        then
            command exit "$@"
        else
            jobs
        fi
        ;;
    *)
        command exit "$@"
        ;;
    esac
}
Mikel
fuente
1

(Wiki de la comunidad, por lo que cada truco pertenece en una respuesta separada).

busca en tu historial todas las formas en que ejecutaste un comando

Es posible que ya sepa sobre Ctrl+ R, pero de esta manera es mucho más suave en mi humilde opinión.

Configure Alt+ Ppara buscar en el historial los comandos que comienzan con lo que ya escribió.

por ejemplo , ls Alt+ P, Alt+ P, Alt+ P buscará hacia atrás a través de todos sus lscomandos.

Necesita poner esto en su /etc/inputrco .inputrcpara bash:

$if mode=emacs
"\ep": history-search-backward
"\en": history-search-forward
$endif

y esto en tu .zshrcpara zsh:

bindkey -M emacs '^[p' history-beginning-search-backward
bindkey -M emacs '^[n' history-beginning-search-forward

Incluso podría ir un paso más allá y hacer que la flecha hacia arriba haga esto.

Mikel
fuente
1

calculadora simple

Puede usar $(( ... ))o expr ...hacer cálculos muy básicos, pero hace una división entera, p. Ej.

$ expr 3 / 2
1

$ expr 1.5 \* 2
expr: non-integer argument

Una mejor manera es usarlo bc.

# do some floating point arithmetic
calc()
{
    echo "scale=3; $*" | bc
}

luego:

$ calc 3 / 2
1.500
$ calc 1.5 \* 2
3.0
Mikel
fuente
1
Mi calculadora es alias py='PYTHONSTARTUP=~/.pythonstartup python'con from math import *;en ese archivo. El problema de la división de enteros sigue sin resolverse, pero es mucho más útil para operaciones más complejas.
maaartinus
1

mejor finalización de pestañas

No creo que nadie haya mencionado la Tabfinalización de la personalización todavía.

Esto es lo que tengo.

Las dos cosas principales que hace son:

  • cada comando se completará en función de lo que el comando espera,
    por ejemplo cd <Tab>, solo sugerirá directorios
  • ignorar el caso,
    por ejemplo, d<Tab>se completará DesktopyDownloads

Para bash:

# custom tab completions
if type complete >/dev/null 2>&1
then
    if complete -o >/dev/null 2>&1
    then
        COMPDEF="-o complete"
    else
        COMPDEF="-o default"
    fi
    complete -a alias unalias
    complete -d cd pushd popd pd po
    complete $COMPDEF -g chgrp 2>/dev/null
    complete $COMPDEF -u chown
    complete -j fg
    complete -j kill
    complete $COMPDEF -c command
    complete $COMPDEF -c exec
    complete $COMPDEF -c man
    complete -e printenv
    complete -G "*.java" javac
    complete -F complete_runner -o nospace -o default nohup 2>/dev/null
    complete -F complete_runner -o nospace -o default sudo 2>/dev/null
    complete -F complete_services service
    # completion function for commands such as sudo that take a
    # command as the first argument but should complete the second
    # argument as if it was the first
    complete_runner()
    {
        # completing the command name
        # $1 = sudo
        # $3 = sudo
        # $2 = partial command (or complete command but no space was typed)
        if test "$1" = "$3"
        then
            set -- `compgen -c "$2"`
        # completing other arguments
        else
            # $1 = sudo
            # $3 = command after sudo (i.e. second word)
            # $2 = arguments to command
            # use the custom completion as printed by complete -p,
            # fall back to filename/bashdefault
            local comps
            comps=`complete -p "$3" 2>/dev/null`
            # "complete -o default -c man" => "-o default -c"
            # "" => "-o bashdefault -f"
            comps=${comps#complete }
            comps=${comps% *}
            comps=${comps:--o bashdefault -f}
            set -- `compgen $comps "$2"`
        fi
        COMPREPLY=("$@")
    }

    # completion function for Red Hat service command
    complete_services()
    {
        OIFS="$IFS"
        IFS='
        '
        local i=0
        for file in $(find /etc/init.d/ -type f -name "$2*" -perm -u+rx)
        do
            file=${file##*/}
            COMPREPLY[$i]=$file
            i=$(($i + 1))
        done
        IFS="$OIFS"
    }
fi

Para zsh:

# set command completions
compctl -a {,un}alias
compctl -b bindkey
compctl -c command
compctl -/ {c,push,pop}d
compctl -E {print,set,unset}env
#compctl -c exec
compctl -f -x "c[-1,exec]" -c -- exec
compctl -j fg
# no -g according to zshcompctl
#compctl -g {ch}grp
compctl -j kill
compctl -c man
compctl -c nohup
compctl -u {ch}own
compctl -o {set,unset}opt
compctl -f -x "c[-1,sudo]" -c -- sudo
compctl -c {whence,where,which}
compctl -M '' 'm:{a-zA-Z}={A-Za-z}'

# make file name completion case-insensitive
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}'
Mikel
fuente
1

Compresión segura

Los programas de compresión eliminan el archivo original por defecto. Eso no me gusta

alias gzip='gzip --keep'
alias bzip2='bzip2 --keep'
alias xz='xz --keep'
alias lzma='lzma --keep'

Aviso de varias líneas

tag() {
    TAG="${TAG} [$1]" exec zsh
}

reset_tags() {
    TAG='' exec zsh
}

color='green'
if [ "${USER}" = 'root' ]; then
    color='red'
fi

export PS1="${TAG} %B%F{yellow} *** %F{blue}%~\

%F{yellow}%(1j.[%j] .)%F{red}%(?..(%?%) )%F{${color}}%n@%m %F{blue}%# %f%b"
export RPS1='%B%F{blue}%D{%Y-%m-%d} %F{green}%D{%H:%M:%S}'
export PS2='%B%F{red}%n@%m%k %B%F{blue}%_> %b%f%k'
unset color
  • Muestra el directorio actual en una línea separada. Útil cuando se maneja un árbol de directorio profundo en un terminal de 80 columnas.
  • Tener un reloj en la esquina es una gran cosa si usas un entorno gráfico. Este aviso muestra la hora. Desafortunadamente tienes que presionar enter para actualizarlo.
  • Puede mostrar "etiquetas" con variables de entorno. Ejemplo:

    tag 'DONT SHTUDOWN!!'
    reset_tags
  • El código se basa al menos parcialmente en esto .

Configuraciones de historial

dont_log() {
    HISTFILE="/dev/null" TAG="${TAG} %B%F{red}[LOGGING DISABLED]" zsh
}

if [ "${HISTFILE}" != '/dev/null' ]; then
    # history
    export HISTFILE="${HOME}/.zsh/history"
    export HISTSIZE="4096"
    export SAVEHIST="4096"

    # Don't overwrite, append!
    setopt APPEND_HISTORY

    # Write after each command
    # setopt INC_APPEND_HISTORY

    # Killer: share history between multiple shells
    setopt SHARE_HISTORY

    # If I type cd and then cd again, only save the last one
    setopt HIST_IGNORE_DUPS

    # Even if there are commands inbetween commands that are the same, still only save the last one
    setopt HIST_IGNORE_ALL_DUPS

    # Pretty    Obvious.  Right?
    setopt HIST_REDUCE_BLANKS

    # If a line starts with a space, don't save it.
    setopt HIST_IGNORE_SPACE
    setopt HIST_NO_STORE

    # When using a hist thing, make a newline show the change before executing it.
    setopt HIST_VERIFY

    # Save the time and how long a command ran
    setopt EXTENDED_HISTORY

    setopt HIST_SAVE_NO_DUPS
    setopt HIST_EXPIRE_DUPS_FIRST
    setopt HIST_FIND_NO_DUPS
fi
  • Descaradamente robado de aquí .
  • Agregué soporte para deshabilitar explícitamente el registro. Útil si se trata de programas que esperan contraseñas como argumento de la CLI.
revs stribika
fuente
0
  • bashrc : soy un usuario de zsh, así que tengo algunas líneas en mi bashrc que inician zsh si está disponible en un sistema.
  • zshrc : en lugar de copiar mi zshrc de algo como grml (aunque zshrc es bastante bueno, así que si no quieres rodar el tuyo, probablemente sea uno de los mejores) escribo mi propio zshrc.
    • Tengo un aviso personalizado. Entre otras cosas, muestra el código de retorno del último comando si no era igual a 0.
    • Tengo algunos alias Debido a que tengo cuentas en bastantes servidores, a veces tengo que realizar comprobaciones para saber qué versión de un comando está disponible en un sistema y configurar el alias en consecuencia.
    • Establezco mi variable PATH.
    • Configuré algunas otras variables de entorno (por ejemplo, $ EDITOR)
  • vimrc : soy un usuario de vim, así que tengo un esquema de color personalizado y uno personalizado.
  • screenrc : uso la pantalla GNU para evitar tener que abrir múltiples terminales y preservar el historial sin estar conectado, así que tengo mi propio screenrc.
Christoph Wurm
fuente
0

¡Si puede ENCENDER EL AUTOCOMPLETO Y NOMBRE DE ARCHIVO CORRECCIÓN DE DETERMINACIÓN! Estas son probablemente las dos cosas que te ahorrarán más tiempo. Luego, aprenda a usarlos: Bash y Zsh tienen finalización de tabulación. Ksh tiene una barra invertida de escape ineficiente, por lo que recomendaría contra Ksh.

Uso Zsh, pero los alias como este funcionarían en casi cualquier shell, excepto Csh:

alias l='ls -FC --color=tty'
alias ls='ls -FC --color=tty'
alias h=history
alias m=more
alias vi=vim
alias cx='chmod +x'

Parece que debería haber un alias para 'ps', pero me encuentro usando 'ps' en una amplia variedad de formas, y hasta ahora no he encontrado nada.

En Zsh, configure su variable RPROMPT (¡no un error tipográfico!):

RPROMPT='%d'

El directorio completo aparece en el lado derecho de la línea de comando, listo para cortar y pegar. Más sobre eso más tarde.

Debe usar un Vim moderno correctamente compilado, debido a la capacidad de tener múltiples ventanas vim en un archivo y múltiples buffers. Su .vimrc podría tener cosas como esta:

set mouse=c
set ml
set mls=5
set nowrap
set nobackup
set nonu
set showmatch
set tabstop=4
set shiftwidth=4
set showmode
set showcmd
set ruler
set notextauto
set laststatus=2
set mps=(:),{:},[:],<:>
set modelines=0

Muchos de ellos son preferencias personales, pero creo que las pestañas de 8 espacios hacen que el código sea menos legible, y hay un estudio flotando para probarlo.

Además, el "mouse = c" es importante. No debería usar el mouse para moverse dentro de un archivo. Quitar las manos del teclado, tocar el mouse y moverlas hacia atrás es lento. Utilice el movimiento del cursor "hjkl" y otras teclas de movimiento del cursor y paginación del teclado.

Si está utilizando X11, debe hacer algunas cosas con su configuración de Xterm. Esto sale de mi archivo .Xresources:

XTerm*VT100.scrollBar: true
XTerm*VT100.saveLines: 1000
XTerm*VT100.cutNewLine: false 
XTerm*VT100.cutToBeginningOfLine: false
XTerm*VT100.charClass: 33:48,35:48,37:48,42:48,45-47:48,64:48,95:48,126:48
XTerm*VT100*translations: #override \n\
    <Key>F2: insert-selection(PRIMARY,CUT_BUFFER0)

Dale a Xterm una barra de desplazamiento por defecto, guarda 1000 líneas de texto en el búfer, eso es bastante estándar.

La directiva charClass hace que una "palabra" incluya cosas como '.', '/' Y '*'. Haga doble clic en cualquier parte de un nombre de archivo separado por '/', y obtendrá todo, menos caracteres ':'.

cutToBeginningOfLine funciona con el RPROMPT de Zsh anterior. Haga clic tres veces en la ruta del directorio de trabajo actual que aparece en el RHS de su línea de comando, y selecciona solo la ruta: la copia se detiene al comienzo de la palabra. Muy eficiente una vez que estés acostumbrado.

Los recursos X anteriores también la convierten en una clave de pegado. De esa manera, una vez que haya copiado (probablemente usando el mouse) puede pegar sin mover la mano hacia el mouse para hacer clic.

Bruce Ediger
fuente
FWIW, la finalización del nombre de archivo es Esc``Esco Esc``=en ksh, y Tabfunciona en ksh93. En caso de que alguien esté atrapado con él o lo prefiera.
Mikel
0

Agregar el valor de retorno distinto de cero del último comando es una gran idea. Creo que el póster original preguntaba específicamente sobre .profile / .cshrc / .bashrc. Vale la pena mencionar la lista de otros archivos RC comúnmente personalizados, pero me limitaría a las personalizaciones de shell para esta pregunta.

También agregué recientemente una bandera en mi mensaje que aparece cuando el shell se ejecuta bajo la pantalla. Utiliza el comando "ptree" de solaris para buscar procesos ancestrales, pero puede usar el comando "pstree" en Linux para hacer lo mismo.

SCREEN=""
if [ -f /usr/bin/ptree ]; then
   if ptree $$ | grep -v grep | grep -w screen > /dev/null 2>&1; then
       SCREEN="SCREEN "
   fi
fi

Me tomó unos minutos descubrir cómo incrustar el código de retorno del último comando, así que lo publicaré aquí.

PROMPT_COMMAND='if [ "$?" = 0 ]; \
        then RC=""; \
        else RC="RV=$? "; fi; PS1="% ${SCREEN}\h $RC\w\n% "'

Estoy seguro de que podría hacerse más hermoso. :-)

Consejo futuro, tenga cuidado al leer $? después de usar "if [". Si el corchete izquierdo está incorporado, no anulará el valor de $ ?. Pero si usa un shell donde [no está integrado, entonces restablecerá el valor de $? Después de la prueba. ¿Es más seguro asignar $? en una variable temporal de inmediato y luego pruebe esa variable.

Chris Quenelle
fuente
Su respuesta probablemente debería ser un comentario ... ¡Me gusta esto!
VxJasonxV
0

muestra el archivo cambiado más recientemente

A menudo, quiero mirar el archivo más reciente. por ejemplo, podría estar en el directorio de registros y quiero ver qué archivo es más reciente porque ese es el primer lugar para ver por qué algo no funciona.

ls -lt | head es un tipo engorroso, así que aquí hay una alternativa:

# show the most recently changed file
latest()
{
    if test $# -ne 0
    then
        /bin/ls -t -1 -d "$@" | head -n 1
    else
        /bin/ls -t -1 -d * | head -n 1
    fi
}

También toma un comodín o una lista de archivos, p. Ej.

$ latest mail* syslog*
syslog

lo cual es especialmente útil si todos sus archivos de registro tienen una marca de tiempo en su nombre. Puede encontrar el último registro para ese programa, sin preocuparse de en qué formato está la marca de tiempo.

$ touch -d 'Feb 1' mylog.20110201
$ touch -d 'Feb 2' mylog.20110202
$ touch -d 'Feb 3' mylog.20110203
$ latest mylog*
mylog.20110203

Y aquí hay una versión extendida que admite una -<number>opción para imprimir <number>líneas en lugar de una.

# show the most recently changed file
latest()
{
    local count=1               # how many files to print
    local promptlines=5         # how many lines to leave for the prompt
                                # when printing a screenful with -s
    local usage="Usage: latest [-n <number>] [-s] [--] [pattern]"
    while test $# -gt 0
    do
        case $1 in
        # -- = stop processing options
        --)
            shift
            break
            ;;
        # -n <number> = <number> files
        -n)
            if test -n "$2"
            then
                count=$2
                shift 2
            else
                echo "$usage" 1>&2
                return 1
            fi
            ;;
        # -s = one screenful
        -s)
            count=$((LINES - promptlines))
            shift
            ;;
        # -<number> = <number> files
        -[0-9]*)
            count=${1#-}
            shift
            ;;
        # anything else starting with a minus is a usage error
        -*)
            echo "$usage" 1>&2
            return 1
            ;;
        *)
            break
            ;;
        esac
    done

    if test $# -ne 0
    then
        /bin/ls -t -1 -d "$@" | head -n $count
    else
        /bin/ls -t -1 -d * | head -n $count
    fi
}
Mikel
fuente