![Bash 脚本自动化问题](https://linux22.com/image/992402/Bash%20%E8%84%9A%E6%9C%AC%E8%87%AA%E5%8A%A8%E5%8C%96%E9%97%AE%E9%A2%98.png)
我断章取义了这一点,但我的脚本的这一部分无法正确执行:
latest=$(ls ~/Videos/ -t | head -n 1 | sed 's/ /\\ /g')
mpv ~/Videos/$latest
我正在尝试自动播放添加到我的视频目录中的最新文件。出现以下错误:
Error parsing option t (option not found)
Setting command line option '--t=' failed.
Exiting... (Fatal error)
答案1
ls
解析is的输出通常来说这不是一个好主意。当输出是视频文件列表时这样做绝对是一个糟糕的想法。视频文件几乎肯定会包含空格和其他奇怪的字符,这很可能会导致问题。这里有一个更安全的替代方案,可以做同样的事情:
latest="$(stat --printf '%Y\t%n\0' * | sort -zk1 | tail -zn1 | cut -f2-)"
mpv "$latest"
或者,如果你tail
没有-z
标志:
latest="$(stat --printf '%Y\t%n\0' * | sort -rzk1 | awk -F'\t' -vRS='\0' '{print $2; exit}'
或者
latest="$(stat --printf '%Y\t%n\0' * | sort -rzk1 | perl -00pe 's/^\d+\s+(.*?)\0.*/$1/s')"
注意引用。你应该总是引用你的变量除非您绝对确定引用会破坏某些内容。此解决方案用于stat
打印文件的修改日期 ( %Y
)、制表符 ( \t
)、文件的名称 ( %n
) 和 NULL 字符 ( \0
)。这将提供给 sort,后者按第一个字段 ( -k1
) 进行排序,即日期并期望以空字符分隔的输入 ( -z
)。然后传递它tail
以获取最后一行 ( -n1
) 以空字符分隔的 ( -z
) 行,最后cut
删除日期仅留下文件名。这确保您可以处理任意文件,甚至是名称中带有换行符的文件。
如果不知道 中的文件名称,则很难诊断您看到的错误~/Videos
。主要问题是您没有引用变量的名称,并且由于似乎有一个带有 的文件--t
,因此将其作为参数。如果您知道文件名永远不会包含换行符,您也可以执行以下操作:
latest="$(ls ~/Videos/ -t | head -n 1)"
mpv ~/Videos/"$latest"
但这确实是一个坏习惯,永远不应该在生产代码中使用。