Bash“最新目录”的工作方式不同于CL和Script

时间:2019-01-01 18:31:01

标签: bash

创建某些目录后,我一直在一些脚本中使用cd "$(\ls -1dt ./*/ | head -n 1)"进入新目录。我决定在我的bash_profile中放置一个别名:

alias newest="cd $(\ls -1dt ./*/ | head -n 1)"

但是,当我从命令行运行newest时,它会转到另一个目录,尽管我不知道这是为什么要选择该目录,但这还是按字母顺序排列的第一个目录。

cd "$(\ls -1dt ./*/ | head -n 1)"直接粘贴到命令行中可以正常工作。这是怎么回事?

1 个答案:

答案 0 :(得分:4)

根本不在脚本中完全使用ls -t -有关其不可靠的原因,请参见ParsingLs,相反,请参见BashFAQ #3。但忽略这一点,解决当前紧迫问题的最小方法是使用函数:

newest() { cd "$(command ls -1dt ./*/ | head -n 1)"; }

您的别名在定义时(而不是在调用时)运行命令替换 。如果真的希望它仍然是别名,则可以在外部使用单引号来防止该命令替换过早发生:

alias newest='cd "$(\ls -1dt ./*/ | head -n 1)"'

可靠,最佳实践的方法是什么样的?也许:

cdNewest() {
   local latest='' candidate
   set -- */
   [[ -d $1 ]] || return  # handle case where no directories exist so glob did not expand
   latest=$1; shift
   for candidate; do
     [[ $candidate -nt $latest ]] && latest=$candidate
   done
   cd -- "$latest"
}

...它根本不运行两个外部命令(lshead),而根本不运行(并且还避免了命令替换和管道的需求,这两个命令都非常高-开销,总计)。