首页 > 解决方案 > 使用 f=$(cd dir | ls -t | head) 获取目录中最新文件的路径不尊重“dir”

问题描述

我想使用这部分代码从路径中获取文件(zip 文件)file=$(cd '/path_to_zip_file' | ls -t | head -1)。相反,我在运行此文件的目录中获取了我的 .sh 文件。

为什么我不能从/path_to_zip_file

下面是我在 .sh 文件中的代码

file=$(cd '/path_to_zip_file' | ls -t | head -1)
last_modified=`stat -c "%Y" $file`;
current=`date +%s`
echo $file

if [ $(($current-$last_modified)) -gt 86400 ]; then
        echo 'Mail'
else
        echo 'No Mail'
fi;

标签: bashsh

解决方案


如果您要使用ls -t | head -1(您不应该使用),则cd需要将其更正为先前的命令(发生 ls发生之前),而不是管道组件(与 并行 ls运行,其标准输出连接到ls的标准输入):

set -o pipefail # otherwise, a failure of ls is ignored so long as head succeeds
file=$(cd '/path_to_zip_file' && ls -t | head -1)

更好的实践方法可能如下所示:

newest_file() {
  local result=$1; shift                      # first, treat our first arg as latest
  while (( $# )); do                          # as long as we have more args...
    [[ $1 -nt $result ]] && result=$1         # replace "result" if they're newer
    shift                                     # then take them off the argument list
  done
  [[ -e $result || -L $result ]] || return 1  # fail if no file found
  printf '%s\n' "$result"                     # more reliable than echo
}

newest=$(newest_file /path/to/zip/file/*)
newest=${newest##*/}  ## trim the path to get only the filename
printf 'Newest file is: %s\n' "$newest"

要了解${newest##*/}语法,请参阅bash-hackers 的参数扩展 wiki

有关为什么ls在脚本中使用(向人类显示的输出除外)是危险的更多信息,请参阅ParsingLs

Bot BashFAQ #99如何从目录中获取最新(或最旧)的文件?- 和BashFAQ #3如何根据某些元数据属性(最新/最旧的修改时间、大小等)对文件进行排序或比较?)在提出这个问题的更大背景下进行了有用的讨论。


推荐阅读