mv命令移动文件但报错:无法统计找不到文件或目录。

3
我希望有经验的人能够找到我所忽略的显而易见的问题,或者能够帮助我解决mv和rsync产生的错误。您准备好接受挑战了吗?
基本想法是:我有一个bash脚本,在其中自动将文件从一个目录移动到另一个目录。
问题是:当我运行脚本时,有时会从mv命令得到以下错误:“mv: cannot stat '/shares/directory with spaces/test file.txt': No such file or directory”。vm命令的错误代码是1。更奇怪的是,有时文件移动实际上会成功。
此外,我在脚本中有一个逻辑分支,交替使用rsync移动/复制特定文件(与上述mv命令相同的本地文件系统源和目标)。我遇到了一个类似于stat()系统调用的错误:
“rsync: link_stat "/shares/directory with spaces/test file.txt" failed: No such file or directory (2) rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1070) [sender=3.0.9]”
当运行脚本时,这个错误不总是出现。有时它会完成文件移动而没有任何抱怨,而其他时候连续运行脚本时会始终返回错误。
还有一个额外的因素需要注意(我越来越怀疑这是我的困扰的关键因素):/shares/目录是Dropbox安装监视的目录,意味着它被监视并由Dropbox安装镜像。此时,我无法确定dropboxd是否以某种方式锁定了该文件,或者类似于此类的情况,使其无法进行stat操作。明确地说,这些文件最终会在没有进一步干预的情况下从此状态中释放,并且可以使用mv移动。
代码如下:
“mv -v --no-clobber "${SOURCEPATH}${item}" "${DESTINATIONPATH}${item}"”
更多信息:
以下内容可能与问题有关:
- mount指示文件系统为ext4 - 假定,由于脚本是由root运行的,所以所有权和权限不应该是问题。尤其是如果文件系统不是基于fuse的。 - 路径中的基本“目录”(例如/shares/)是指向同一文件系统上另一个目录的符号链接。 - Linux的版本是Debian。

故障排除:
为了消除变量扩展或其内容的任何问题,我尝试像这样硬编码bash脚本:
mv -v --no-clobber "/shares/directory with spaces/test file.txt" "/new destination/directory with spaces/test file.txt" 通过 ls -al 验证 "test file.txt" 存在。参考权限为:-rw-r--r--
不幸的是,这也导致相同的错误。

我能想到的其他可能问题以及我为了尝试排除它们所做的事情:

>> 可能问题: 慢的HDD(或驱动器处于低功耗模式)或外部USB驱动器
>> 结果: 所有驱动器都是本地SATA磁盘,设置为不停放磁头。此外,即使强制从文件系统进行一致读取,仍然会发生相同的错误。

>> 可能问题: 非Linux、NFS或fuse基础的文件系统
>> 结果: 没有,源和目标都在同一个本地文件系统上,并且 mount 表示文件系统是ext4

>> 可能问题: 文件路径中的空格或其他不可打印字符
>> 结果: 验证源路径和目标路径都正确地包含在引号中

>> 可能问题: 转义换行符后的续行问题(换行符后的空格)
>> 结果: 确保命令都在一行上,仍然是相同的错误

>> 可能问题: globbing(在指定要移动的文件时使用*)
>> 结果: 没有,在路径和名称中直接指定每个文件

>> 可能问题: 由于使用本地路径而导致的路径混淆
>> 结果: 没有,文件路径从 / 开始完全合格

>> 可能问题: 实际上没有在指定的路径中找到文件
>> 结果: 没有,在执行脚本之前通过 ls -al 验证了文件存在

>> 可能问题: --no-clobber 的 mv 导致问题
>> 结果: 没有,尝试了没有它,相同的错误

>> 可能问题: 只有通过Dropbox同步到文件系统的文件存在问题
>> 结果: 没有,直接通过 touch new-local-file.txt 创建本地文件也会产生相同的 stat() 错误

我的分析: mvrsync产生类似的stat()错误,这让我相信:
  • 在bash脚本中存在某些系统性的潜在边界情况(例如文件权限/所有权或文件忙)没有被考虑;或者
  • 同样的bug困扰了我在mvrsync场景中。
期望结果: 1. 可以确定间歇性错误的根本原因。 2. 可以解决或解决根本原因。 3. 可以改进bash脚本,优雅地处理发生错误的情况。

更多信息:我编辑了bash脚本,在mv的退出代码> 0时在文件上运行/usr/bin/stat。我打开了2个shell:在其中一个shell中,我运行了while true; do find . -exec stat {} \;; done。我将文件复制到源路径中,并在循环的stat中看到它正常显示。在另一个shell中,我运行了bash脚本。 mvstat抛出错误“无法stat ...没有这样的文件”。尽管来自'mv'的错误,但实际上已移动文件。这解释了为什么stat会引发错误,但并不解释为什么mv会这样做。成功的文件移动也通过循环的stat输出得到了验证。 - John Mark Mitchell
1个回答

1
因此,通过更多的故障排除,我在脚本中找到了一个错误的rsync语句,它在条件执行时(因此似乎行为不一致)早在200行之前。该rsync --archive ...语句将/shares/作为其源目录传递,因此影响了/shares/directory with spaces/子目录。这个子目录是我上面帖子中提到的令人困扰的mv命令的${SOURCEPATH}。
最终,缺少rsync --dry-run标志导致脚本后来期望传递给mv处理的文件被覆盖。
感谢所有花时间阅读我的帖子的人。虽然我很失望地花费了我的和你们的时间,但让人放心的是:
-计算机并不是非理性的
-我不是疯了
-linux文件系统中没有一些险恶的根深蒂固的错误

对于那些因cannot stat错误而遇到此帖子的人,请阅读我上面的故障排除笔记。这个列表经过了许多研究,其中之一可能是您的问题。如果不是,请继续调试,一定有解释。祝好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接