Bash: 将别名或函数作为参数传递给程序

Bash: Pass alias or function as argument to program

我经常需要处理目录中的最新文件。

通常我这样做:

ls -rt

然后打开最后一个 vim 或更小的文件。

现在我想生成一个别名或函数,例如

lastline() {ls -rt | tail -n1}
# or
alias lastline=$(ls -rt | tail -n1)

调用lastline输出目录中的最新文件,很好。 但是调用

less lastline

想打开不存在的文件"lastline"。

如何让 bash 执行函数或别名(如果可能)而无需大量键入 $() 或 ``? 或者还有其他方法可以达到同样的效果吗?

感谢您的帮助。

像这样使用命令替换:

lastline() { ls -rt | tail -n1; }
less "$(lastline)"

或通过管道传送到 xargs:

lastline | xargs -I {} less '{}'

您正在解析 ls,这非常糟糕。此外,如果最后修改的“文件”是一个目录,您将lessing/viming 一个目录。

因此您需要一种可靠的方法来确定当前目录中最后修改的文件。您可以使用如下辅助函数(将其放入 .bashrc):

last_modified_regfile() {
    # Finds the last modified regular file in current directory
    # Found file is in variable last_modified_regfile_ret
    # Returns a failure return code if no reg files are found
    local file
    last_modified_regfile_ret=
    for file in *; do
        [[ -f $file ]] || continue
        if [[ -z $last_modified_regfile_ret ]] || [[ $file -nt $last_modified_regfile_ret ]]; then
            last_modified_regfile_ret=$file
        fi
    done
    [[ $last_modified_regfile_ret ]]
}

然后你可以定义另一个函数来 vim 最后找到的文件:

vimlastline() {
    last_modified_regfile && vim -- "$last_modified_regfile_ret"
}

您甚至可以 last_modified_regfile 接受可选参数:它将在其中找到最后修改的常规文件的目录:

last_modified_regfile() {
    # Finds the last modified regular file in current directory
    # or in directories given as arguments
    # Found file is in variable last_modified_regfile_ret
    # Returns a failure return code if no reg files are found
    local file dir
    local save_shopt_nullglob=$(shopt -p nullglob)
    shopt -s nullglob
    (( $# )) || set .
    last_modified_regfile_ret=
    for dir; do
        dir=${dir%/}
        [[ -d $dir/ ]] || continue
        for file in "$dir"/*; do
            [[ -f $file ]] || continue
            if [[ -z $last_modified_regfile_ret ]] || [[ $file -nt $last_modified_regfile_ret ]]; then
                last_modified_regfile_ret=$file
            fi
        done
    done
    $save_shopt_nullglob
    [[ $last_modified_regfile_ret ]]
}

然后你甚至可以相应地改变vimlastline:

vimlastline() {
    last_modified_regfile "$@" && vim -- "$last_modified_regfile_ret"
}