如何仅使用 Bash 数组反向打印目录的内容?

How can I print the contents of a directory in reverse just using Bash arrays?

目前,我正在做这个家庭作业:

Write a Bash script, reverse.sh, which reverses the contents of a directory passed as a parameter. Assuming /my/dir contains cache cron games lib log run tmp, your program reverse.sh /my/dir will return tmp run log lib games cron cache. Use an array and two functions: main() and reverse(). You will manually manipulate the list as we did today. DO NOT use the built-in command sort -r.

现在,我决定先使用一个函数来获得正确的输出,这不是我的问题。到目前为止,这是我的脚本:

function main(){
    p=
    cd $p
    reverse $p
}

function reverse(){
    local p2=
    local ARRAY=()
    local count=0
    for entry in $p2*
    do
     ((count++))
     ARRAY+=($entry)
    done
    while [ $count -gt -1 ]; do
     echo ${ARRAY[$count]}
     ((count--))
    done
}
main

但是,无论我在 运行 脚本时添加什么目录作为参数,我每次都得到相同的输出。

如果您的脚本要将 /my/dir 作为参数,您需要

for entry in $p2/*

原样,它适用于 main /my/dir/。除了目录名称包含在每个数组元素中之外。您可以使用 basename 或 cd 修复它。

但是如果您在脚本中对 main 的调用应该传递命令行参数,则您需要结束脚本

main ""

p= 将不起作用,因为未使用任何参数调用 main(参数不会自动从命令行传递给函数)。修复是将所有命令行参数传递给函数:

    main $@

在 Bash

中取消偏移位置参数

我确定您的家庭作业正在尝试教给您一些特别的东西,但即使您应该用 Bash 数组模拟堆栈,这也需要很长的路要走。在 Bash 中,您可以通过利用位置参数和 shift 内置函数来使用单个局部变量来完成此操作。例如:

# Function to sort names by emulating unshifting onto a stack.
reverse () {
    local -a result
    for dir in "$@"; do
        result=("" "${result[@]}") # unshift  onto stack
        shift                        # remove   from positional params
    done
    echo "${result[@]}"
}

reverse cache cron games lib log run tmp

tmp run log lib games cron cache

出于演示的目的,此函数假设正在向其传递要排序的姓名列表;它不假设您如何收集这些名称,因为 bike-shedding. However, on systems with GNU ls, you might consider reverse $(ls -Q /path/to/dir) (do not quote the command substitution) 作为一个实用的解决方案,可以处理最常见的用例。

自行车脱落

专业质量的脚本需要比合理大小的示例中提供的更多的防弹功能。注意事项包括:

  • 处理文件名中的空格、换行符和其他合法(但不常见)字符。
  • 处理 nullglob 扩展。
  • 正在测试 glob 和参数的目录属性。
  • 处理符号链接、absolute/relative 路径和各种扩展验证。
  • 处理超过 getconf ARG_MAXMAX_ARG_STRLEN.
  • 的硬编码值的 glob
  • 等等,令人作呕。

我的建议是为您已知的数据集编写 "good enough" 的代码,而不是试图应对所有可能的边缘情况。了解您的数据和环境始终很重要,这样您就不会过度设计问题。