Quais personalizações você fez no seu perfil de shell para aumentar a produtividade?

25

Sei que algumas pessoas têm alguns scripts de inicialização e outras personalizam o prompt. Um desenvolvedor usa aliases curtos para o longo caminho que ele costuma visitar e os comandos frequentes que ele executa.

Quais são todas as customizações efetivas que você fez no seu perfil UNIX para aumentar a produtividade e a facilidade de uso?

San
fonte
deve ser CW, não pode ser respondido objetivamente.
akira
Concordo. No entanto, não havia opção para a CW. :-(
San
@akira @Michael Enfrento essa situação com frequência. Seria ótimo se os moderadores pudessem editar / publicar / redirecionar a pergunta. Porque o comentário que você deixa não ajuda muito o usuário para alcançar o que ele realmente deseja. Sem ofensa, apenas uma sugestão. Espero que você entenda.
San
Se você quiser fazer uma pergunta no wiki da comunidade, sinalize-o para atenção do moderador. Veja o FAQ da wiki da comunidade .
Gilles 'SO- stop be evil'

Respostas:

11

.vimrc

salve o arquivo com permissões de root digitando w!!:

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


.bashrc

Não se preocupe com dispositivos ou arquivos binários ao greping:

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


Compartilhe código na Web (como pastebin, mas mais simples), cat 1337.sh | webshare

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

Ele devolve um pequeno URL na sua área de transferência; você pode anexar ?whatever-langao URL retornado para realçar a sintaxe e numerar as linhas.


.inputrc

Use o modo vi em tudo que usa a biblioteca readline (muitos programas):

set editing-mode vi
set keymap vi
Shawn J. Goff
fonte
Ótimas dicas que eu nunca soube.
São
7

crie um diretório e cd em um comando

Na maioria das vezes mkdir, meu próximo comando é cd <that dir>.

Isso economiza digitação:

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

por exemplo:

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

Outra coisa que acho útil é uma maneira fácil de criar um diretório descartável. por exemplo, se estou compilando um programa ou mesmo tentando reproduzir um problema neste site. Às vezes eu posso esquecer de limpar o diretório.

# 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
}

mostrando funcionando:

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

Estou contando com a limpeza do sistema /tmpapós uma reinicialização, mas seria possível melhorar isso, por exemplo, faça com que ele exclua o diretório temp após sair do shell.

Mikel
fonte
Eu amei a opção mcd. Bom, obrigado.
São
+1 Uso minha versão mcdhá muitos anos e adicionarei algo como em mtdbreve.
Maaartinus 7/03
Eu defini o meu mtd() { mcd $TMP/`date +%y%m%d-%H%M%S-%N`; }. Provavelmente falta uma portabilidade, mas é bom o suficiente para mim.
Maaartinus 7/03
4

Eu gostaria que meu prompt do bash mostrasse o código de saída do comando anterior, se fosse diferente de zero. Também gosto da minha concha para me animar quando a uso, então acrescentei um pouco de tolice:

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

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

então, quando executo comandos, recebo um bom feedback visual:

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

edit : isso é algo que eu coloquei no meu ~ / .bashrc

jsbillings
fonte
Muito interessante. Mas tenho uma dúvida. Onde o código deve residir?
São
Em .bashrcpresumivelmente.
Mikel
sim, que está em minhas ~ / .bashrc
jsbillings
Vai tentar isso ..
San
4

até N

pule N diretórios para cima na árvore de diretórios

Em vez de digitar

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

você apenas digita

up 4

e um

cd -    

vai te trazer de volta

Coloque a função no seu .bashrc para usá-lo.

# (c) 2007 stefan w. GPLv3          
function up {
ups=""
for i in $(seq 1 $1)
do
        ups=$ups"../"
done
cd $ups
}
Usuário desconhecido
fonte
Uau .. que é uma boa idéia .. #
San 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

(Alterna as teclas Escape e Caps Lock).

polemon
fonte
+1 para remapeamento de chaves, meu Caps Lock está mapeado para Return, QUEM PRECISA CAPS BLOQUEIO DE QUALQUER FORMA?
wag
11
Eu sou um usuário do Vim. É comum para os usuários do Vim mapear Escape para Caps Lock. O usuário do Emacs tende a mapear o Control para Caps Lock.
precisa saber é
1

Eu estrago no meu bashrc, já que uso muito o terminal (isso me faz aprender rápido e aprender coisas interessantes para usar, além de ferramentas interessantes). Eu costumo definir muitas funções no meu bashrc. Exemplos:

Extrair arquivos:

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
}

renomeie arquivos e pastas:

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
}

e assim para dividir arquivos grandes em vários pequenos:

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
}

Também editei muitos aliases, pois acho que é muito mais fácil usar um comando com argumentos como padrão em alguns casos (como nos comandos ls, grep e small) e depois digitar tudo isso sempre.

user2648
fonte
1

(Wiki da comunidade, portanto, cada truque pertence a uma resposta separada.)

logout seguro

Ctrl+ Dé a maneira mais fácil de sair do shell, mas se você ainda tiver trabalhos em execução, ele sairá feliz do shell de qualquer maneira. Por padrão, isso significa que todos os programas que você estava executando dentro desse shell serão mortos.

Algumas conchas apenas permitem que você saia após pressionar Ctrl+ Dduas vezes, mas ainda é muito fácil fazer isso acidentalmente.

Então, em vez disso, adicione a .bashrcou .zshrcou qualquer arquivo de configuração que você preferir.

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
fonte
1

(Wiki da comunidade, portanto, cada truque pertence a uma resposta separada.)

pesquise no seu histórico todas as maneiras pelas quais você executou um comando

Você já deve saber sobre o Ctrl+ R, mas esse caminho é muito mais suave no IMHO.

Configure Alt+ Ppara pesquisar no histórico os comandos que começam com o que você já digitou.

por exemplo , ls Alt+ P, Alt+ P, Alt+ P pesquisará todos os seus lscomandos para trás .

Você precisa colocar isso no seu /etc/inputrcou .inputrcpara bash:

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

e isso no seu .zshrcpara zsh:

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

Você pode dar um passo adiante e fazer a seta para cima fazer isso.

Mikel
fonte
1

calculadora simples

Você pode usar $(( ... ))ou expr ...fazer cálculos muito básicos, mas faz divisão inteira, por exemplo

$ expr 3 / 2
1

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

Uma maneira melhor é usar bc.

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

então:

$ calc 3 / 2
1.500
$ calc 1.5 \* 2
3.0
Mikel
fonte
11
Minha calculadora é alias py='PYTHONSTARTUP=~/.pythonstartup python'com from math import *;nesse arquivo. O problema da divisão de números inteiros permanece sem solução, mas é muito mais útil para operações mais complexas.
Maaartinus 7/03
1

melhor conclusão da guia

Acho que ninguém mencionou a personalização do Tabpreenchimento ainda.

Aqui está o que eu tenho.

As duas principais coisas que faz são:

  • cada comando será completo, dependendo do que o comando está esperando,
    por exemplo cd <Tab>, apenas sugerirá diretórios
  • ignorar caso,
    por exemplo d<Tab>, ainda será concluído DesktopeDownloads

Para o 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
fonte
1

Compressão segura

Programas de compactação excluem o arquivo original por padrão. Eu não gosto disso.

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

Prompt de várias linhas

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
  • Mostra o diretório atual em uma linha separada. Útil ao manusear uma árvore de diretórios profunda em um terminal de 80 colunas.
  • Ter um relógio no canto é ótimo se você usar um ambiente gráfico. Este prompt mostra a hora. Infelizmente você precisa pressionar enter para atualizá-lo.
  • Você pode exibir "tags" com variáveis ​​de ambiente. Exemplo:

    tag 'DONT SHTUDOWN!!'
    reset_tags
  • O código é pelo menos parcialmente baseado nisso .

Configurações do histórico

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
  • Roubado descaradamente a partir daqui .
  • Eu adicionei suporte para desabilitar explicitamente o log. Útil se você estiver lidando com programas que esperam senhas como um argumento da CLI.
stribika
fonte
0
  • bashrc : Eu sou um usuário zsh, então tenho algumas linhas no bashrc que iniciam o zsh se ele estiver disponível em um sistema.
  • zshrc : Em vez de copiar o meu zshrc de algo como grml (embora o zshrc seja muito bom, por isso, se você não quiser criar o seu, é provavelmente um dos melhores), escrevo o meu próprio zshrc.
    • Eu tenho um prompt personalizado. Entre outras coisas, mostra o código de retorno do último comando, se for diferente de 0.
    • Eu tenho alguns apelidos. Como tenho contas em vários servidores, às vezes tenho que executar verificações para saber qual versão de um comando está disponível em um sistema e definir o alias de acordo.
    • Eu defino minha variável PATH.
    • Defino algumas outras variáveis ​​de ambiente (por exemplo, $ EDITOR)
  • vimrc : Eu sou um usuário do vim, por isso tenho um esquema de cores personalizado e personalizado.
  • screenrc : Eu uso a tela GNU para evitar a necessidade de abrir vários terminais e preservar o histórico sem estar conectado, portanto, tenho meu próprio screenrc.
Christoph Wurm
fonte
0

Se você pode LIGAR A CORREÇÃO AUTOMÁTICA E NOME DO ARQUIVO! Essas são provavelmente as duas coisas que você economizará mais tempo. Em seguida, aprenda a usá-los - Bash e Zsh têm preenchimento de guias. O Ksh tem uma barra invertida de escape ineficiente, então eu recomendaria contra o Ksh.

Eu uso o Zsh, mas aliases como esse funcionariam em quase qualquer shell, exceto o 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 um pseudônimo para 'ps' deve estar lá, mas eu me vejo usando 'ps' de várias maneiras e não encontrei nada até agora.

No Zsh, configure sua variável RPROMPT (não um erro de digitação!):

RPROMPT='%d'

O diretório inteiro aparece no lado direito da linha de comando, pronto para cortar e colar. Mais sobre isso mais tarde.

Você deve usar um Vim moderno compilado adequadamente, devido à capacidade de ter várias janelas vim em um arquivo e vários buffers. Seu .vimrc pode ter coisas 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

Muitas são preferências pessoais, mas acredito que as guias de 8 espaços tornam o código menos legível, e há um estudo por aí para provar isso.

Além disso, o "mouse = c" é importante. Você não deve usar o mouse para se mover dentro de um arquivo. Retirar as mãos do teclado, tocar no mouse e movê-las de volta é lento. Use o movimento do cursor "hjkl" e outras teclas de paginação e movimento do cursor.

Se você estiver usando o X11, faça algumas coisas na sua configuração do Xterm. Isso sai do meu arquivo .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)

Dê ao Xterm uma barra de rolagem por padrão, salve 1000 linhas de texto no buffer, isso é bastante padrão.

A diretiva charClass faz com que uma "palavra" inclua itens como '.', '/' E '*'. Clique duas vezes em qualquer parte de um nome de arquivo separado por '/' e você obtém a coisa toda, menos os caracteres ':'.

cutToBeginningOfLine funciona com o Zsh RPROMPT acima. Clique três vezes no caminho do diretório de trabalho atual que aparece no RHS da sua linha de comando e você escolhe apenas o caminho: a cópia é interrompida no início da palavra. Altamente eficiente quando você estiver acostumado.

Os recursos X acima também transformam a chave em colar. Dessa forma, depois de copiar (provavelmente usando o mouse), você pode colar sem mover a mão de volta ao mouse para clicar.

Bruce Ediger
fonte
FWIW, a conclusão do nome do arquivo é Esc``Escou está Esc``=dentro kshe Tabfunciona ksh93. Apenas no caso de alguém ficar preso ou preferir.
Mikel
0

Adicionar um valor de retorno diferente de zero do último comando é uma ótima idéia. Eu acho que o pôster original estava perguntando especificamente sobre .profile / .cshrc / .bashrc. Vale a pena mencionar a lista de outros arquivos RC comumente personalizados, mas gostaria de apenas personalizar as shell para esta pergunta.

Também adicionei recentemente um sinalizador no meu prompt que aparece quando o shell está sendo executado na tela. Ele usa o comando solaris "ptree" para pesquisar processos ancestrais, mas você pode usar o comando "pstree" no Linux para fazer a mesma coisa.

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

Levei alguns minutos para descobrir como incorporar o código de retorno do último comando, então eu o publicarei aqui.

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

Tenho certeza de que isso poderia ser mais bonito. :-)

Dica para o futuro, tenha cuidado ao ler $? depois de usar "if [". Se o colchete esquerdo for incorporado, ele não substituirá o valor de $ ?. Mas se você usar um shell em que [não esteja embutido, ele redefinirá o valor de $? após o teste. É mais seguro atribuir $? em uma variável temporária imediatamente e, em seguida, teste essa variável.

Chris Quenelle
fonte
Sua resposta provavelmente deve ser um comentário ... Assim!
VxJasonxV 31/01
0

mostra o arquivo alterado mais recentemente

Muitas vezes, quero olhar para o arquivo mais recente. por exemplo, eu posso estar no diretório de logs e quero ver qual arquivo é mais recente, porque esse é o primeiro lugar para ver por que algo não está funcionando.

ls -lt | head é um tipo complicado de digitar, então aqui está uma 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
}

Também é necessário um curinga ou lista de arquivos, por exemplo

$ latest mail* syslog*
syslog

o que é especialmente útil se todos os seus arquivos de log tiverem um carimbo de data / hora em seu nome. Você pode encontrar o log mais recente desse programa, sem se preocupar em que formato está o carimbo de data / hora.

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

E aqui está uma versão estendida que suporta uma -<number>opção para imprimir <number>linhas em vez de uma.

# 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
fonte