首页 > 解决方案 > ls: 无法访问 *.jpg: 没有这样的文件或目录

问题描述

我正在尝试创建一个包含文件列表的变量,以便我可以遍历它们。我这样做是这样的:

FILES=(`ls *.jpg`)
FILES="${FILES[@]}"

当我运行这个脚本时,它只是抛出:

ls: cannot access *.jpg: No such file or directory

对于与此类似的问题,我查看了其他一些答案,我很确定这不是权限问题,因为添加sudo到前面没有任何效果,而我是root. 我还检查了脚本本身的权限,它们是-rwxr-xr-x,所以我认为我在那里很好。

知道如何解决这个问题吗?

标签: bash

解决方案


这个Shellcheck -clean 代码演示了如何使用文件列表可靠地填充 Bash 数组:

#! /bin/bash -p

shopt -s nullglob   # Make globs that match nothing expand to nothing
shopt -s dotglob    # Make globs match files whose names start with dot

files=( *.jpg )

declare -p files
  • Shellcheck可以发现 Bash(和其他 shell)代码的许多问题。如果您在问题中的代码上放置一个shebang行并将其提交给Shellcheck,它会识别出几个问题。
  • shopt -s nullglob防止 glob 模式*.jpg在不匹配时扩展到自身。这种扩展是问题中显示的错误消息的原因。运行代码的目录中没有 '.jpg' 文件,ls被赋予文字参数*.jpg,并且它正确地抱怨该文件*.jpg不存在。
  • 使用shopt -s nullglob问题中的代码将不起作用,因为在没有.jpg文件的目录中运行它会导致它创建目录中所有文件的列表(名称以点开头的文件除外)。如果任何文件名包含空格或 glob 模式,则列表将出现乱码。名称以“-”开头的文件会导致ls做意想不到的事情。
    在 Bash 程序中通常不需要使用输出ls,而且使用它通常很危险。看看为什么你不应该解析 ls(1)Bash Pitfalls #1 (for f in $(ls *.mp3))的输出。
  • shopt -s dotglob确保名称以点开头的文件(例如“.image.jpg”)将包含在列表中。如果您不想这样做,请不要使用。
  • 我替换FILESfiles因为大写变量名有可能与环境变量或 shell 内置变量发生冲突。请参阅正确的 Bash 和 shell 脚本变量大写
  • declare -p filesfiles只是以清晰明确的方式打印值。

推荐阅读