无法创建符号链接 - 没有这样的文件或目录

3

我运行了一个Reddit用户为我编写的命令:

dest=final_dir
files=$(find dir1 dir2 dir3 -type f)


for file_path in $files; do
    IFS='/' read -r -a tokens <<< "$file_path"
    dest_fname="${tokens[1]}.${tokens[0]}"
    ln -s "$PWD/$file_path" "$PWD/$dest/$dest_fname"
done

它应该获取所有子文件夹中的所有文件,并创建一个符号链接到另一个目录,链接名称为filename+filefolder。然而,它只会给我一个错误:无法创建符号链接-没有这样的文件或目录。这里是控制台的截图:https://imgur.com/36F4sdX 有什么想法可能是问题吗?
编辑: 好的,问题似乎是当路径包含空格时,它认为名称停在这个空格处,因此找不到文件。有什么方法可以解决这个问题吗?
这里是脚本应该执行的描述。 我的当前文件系统看起来像这样:
dir1:file1,file2
dir2:file1,file2
如果我现在运行上面的命令,我会得到:
dir3:file1,file2
其他两个文件被跳过,因为它们具有相同的名称。
还有这种情况:
dir1:file1,file3
dir2:file2,file4
在这种情况下,文件将混合为:

目录3: 文件1, 文件2, 文件3, 文件4

然而我想要的是:

目录3: 文件1, 文件3, 文件2, 文件4

在我看来,实现这一点最简单的方法是将源文件夹作为符号链接名称的一部分,像这样:

目录3: dir1-file1, dir1-file3, dir2-file3, dir2-file4

我希望这足够清楚地解释了。

目前问题似乎是当文件或文件夹名称包含任何特殊字符,比如“-”或“_”,它会停止读取该名称。

这导致:

dir1-2: file3-4创建到dir1.file3不存在的符号链接。


5
永远不要使用你完全不了解的代码(尤其是包含 rm -rf 命令的代码)。 - alecxs
4
请勿在问题中发布终端文本截图链接,直接将文本发布在问题中即可。请注意不要更改原意,用通俗易懂的语言表达即可。 - KamilCuk
当然,我首先删除了rm -rf部分。此外,我使用屏幕截图来展示确切的输出。 - Daniel
考虑在脚本开头添加 set -x。这样,Shell 将在扩展但尚未执行命令时回显每个命令,使您能够查看导致问题的命令的详细信息。 - John Bollinger
那实际上非常有用,谢谢。 - Daniel
屏幕截图上大部分字符被隐藏的错误信息根本没有用。没有错误信息,你的解释就没有多少价值了。“好的,问题似乎是当路径包含空格时,它认为名称停在这个空格处,因此找不到文件。” - 那么,在您的代码中哪个步骤(或行)会产生错误结果?files变量是否有错误内容,其中文件名中的空格与文件名之间的空格无法区分?请阅读[mcve]的含义并提供它。 - Tsyvarev
1个回答

6

ln -s 命令并不关心源路径是否存在,因此问题必须出在目标路径上。该命令会创建一个符号链接,因此如果出现文件或目录不存在的错误,则问题必须出在目标链接的路径上,而不是链接的名称。

在您的情况下,目标路径为"$PWD/$dest/$dest_fname"

从它的构造来看,$dest_fname 不包含 / 字符,因此它是一个简单的文件名,没有任何路径组件。

$PWD 表示(shell 的概念中)当前工作目录。除非您更改了该变量或工作目录已被删除,否则 $PWD 将扩展为现有目录的名称。

这就把问题定位到了 $dest 上。脚本没有确保指定的目录存在,因此最有可能的解释是它不存在。考虑添加以下代码:

mkdir -p "$PWD/$dest"

如果您希望在需要时创建目标目录,请在for循环之前立即将此命令添加到您的脚本中。


从它的构造来看,$dest_fname 不包含 / 字符,因此它只是一个简单的文件名,没有任何路径组件。 - Bord81

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