“显示全部可能性? (y 或 n)" 代表 ls 命令

“显示全部可能性? (y 或 n)" 代表 ls 命令

当我尝试在 bash 提示符中用 Tab 键完成文件名时,输出将是许多(> 100)个文件名,shell 会询问Display all <num> possibilities? (y or n)

我可以使用普通ls命令复制此行为吗?

我有一个包含 >400k 文件的目录。意外地ls访问此目录会导致 shell 长时间无响应,同时还会输出输出。Ctrl-C并不能阻止洪水。

答案1

我的解决方案可能有点重,但谁知道呢。

问题是,为了做到这一点,您需要对文件进行计数......这通常是通过以下方式完成的:

$ ls | wc -l

现在,由于内容被写入管道,而不是 stdout,因此完成此操作所需的时间会少一些(写入终端需要一点时间,这在 400k 次调用后会变得很重要)write(2))。这可能仍然需要一些时间,但尽管如此,您可以通过一个简单的测试来实现这一点:

#!/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

然后,只需在文件中设置一个别名.bashrc,即可调用此脚本而不是/bin/ls

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

还要确保它已正确 chmoded:

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

编辑:我添加了一个调用head,以便在输出行ls之后终止。$LIMIT这应该可以节省一些时间(并且实际上使它成为一个更好的解决方案timeout);)

我建议的另一种方法是使用超时。如果ls没有在 5 秒内完成,它应该停止并询问您是否确定。这是一个示例脚本(对多个命令有效,而不仅仅是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

然后你可以设置一些别名,例如:

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'

请注意,我正在测试,$? -eq 124因为...

如果命令超时且未--preserve-status设置,则退出并显示状态 124。

timeout(1)了解更多信息。

相关内容