“Exibe todas as possibilidades numéricas? (y ou n) ”para o comando ls

4

Quando eu tento separar um nome de arquivo no prompt do bash, e a saída deve ter muitos (> 100) nomes de arquivos, o shell pergunta Display all <num> possibilities? (y or n)

Posso replicar esse comportamento com o comando normal ls ?

Eu tenho um diretório com arquivos > 400k. Acidentalmente, ls ing deste diretório me deixa com um shell sem resposta por muitos minutos enquanto evita a saída. Ctrl-C não para o dilúvio.

    
por Bryan Glazer 24.08.2015 / 20:28

1 resposta

2

Minha solução pode ser um pouco pesada, mas bem, quem sabe.

O problema é que, para fazer isso, você precisaria contar os arquivos ... o que geralmente é feito com:

$ ls | wc -l

Agora, como o conteúdo é gravado em um pipe e não stdout, isso levará um pouco menos de tempo para ser concluído (gravar em um terminal demora um pouco, o que pode se tornar significativo com chamadas de 400k para write(2) ). Ainda pode levar algum tempo, mas, no entanto, você pode implementar isso com um teste simples:

#!/bin/bash

LIMIT=1000
n=$(ls "$@" 2>/dev/null | head -n$LIMIT | wc -l)

if [ $n -ge $LIMIT ]; then
    echo "This directory contains more than $LIMIT entries."
    echo -n "Are you sure want to continue? (y/N) "

    read confirm
    if [ "$confirm" = "y" -o "$confirm" = "Y" ]; then
        exec ls "$@"
    fi
else
    exec ls "$@"
fi

Em seguida, basta definir um alias no seu arquivo .bashrc para chamar esse script em vez de /bin/ls :

alias ls='/path/to/my_ls.sh --color=auto'

Certifique-se também de que esteja devidamente chmoded:

$ chmod +x /path/to/my_ls.sh

Edit: Eu adicionei uma chamada para head para que ls seja terminado após $LIMIT linhas de saída. Isso deve economizar algum tempo (e realmente torná-lo uma solução melhor que o timeout one);)

Outra abordagem que sugiro é usar um tempo limite. Se ls não completar em 5s, ele deve parar e perguntar se você tem certeza disso. Aqui está um script de exemplo (válido para vários comandos, não apenas ls ):

#!/bin/bash                                                                                                                                                                                

TIMEOUT=5

if [ $# -le 0 ]; then
    echo "Usage: $0 [command]"
    exit 1
fi

# Try it silently for a few seconds...
timeout $TIMEOUT "$@" >/dev/null 2>&1

if [ $? -eq 124 ]; then
    echo -n "Your command failed to run under "$TIMEOUT"s. "
    echo -n "Retry without a timeout? (y/N) "

    read confirm
    if [ "$confirm" = "y" -o "$confirm" = "Y" ]; then
        exec "$@"
    fi
else
    exec "$@"
fi

Em seguida, você pode definir alguns aliases, como:

alias ls='/path/to/script.sh ls --color=auto'
alias grep='/path/to/script.sh grep --color=auto'
alias cat='/path/to/script.sh cat'

Observe que estou testando $? -eq 124 porque ...

If the command times out, and --preserve-status is not set, then exit with status 124.

Veja timeout(1) para mais informações.

    
por 24.08.2015 / 21:07

Tags