ln命令在文件名中有空格时中断


#!/bin/bash
for i in instances/*; do
#echo $i
if [[ -d "${i}/.minecraft/" ]]; then
echo "${i}/.minecraft/"
if [ -h "${i}/.minecraft/saves" ]; then
rm -f "${i}/.minecraft/saves"
else rm -rf   "${i}/.minecraft/saves";
fi
ln -s saves '"'${i}/.minecraft/saves'"'
fi
done

这是我的脚本链接保存在我的PolyMC设置。问题是,如果DIRECTORY有一个空格,代码将不起作用:

instances/1.19 Sodium/.minecraft/有以下输出:

ln: target 'Sodium/.minecraft/saves"': No such file or directory

也删除'"'仍然有相同的错误

正如大家已经评论的那样,它是而不是关于去除'"',但在双引号内引用你的$i。也不是随机组合的"和'让它工作。

解释:

i包含类似:i="1.19 Sodium"的空格时(这里的双引号是分隔符,而不是字符串的字符),

ln -s saves '"'${i}/.minecraft/saves'"'

被视为:

ln -s saves '"'1.19 Sodium/.minecraft/saves'"'

在此上下文中,单引号是字符串分隔符,而双引号是字符串中的任何(不需要的)字符。

读作:

  1. ln
  2. 字段分隔符
  3. -s
  4. 字段分隔符
  5. saves
  6. 一个字符串(用单引号分隔),由一个字符"连接到单词1.19
  7. 空格(来自i)被解释为字段分隔符
  8. Sodium/.minecraft/saves连接到一个字符"的字符串(用单引号分隔)。

则完全等价于:ln -s saves '"1.19' 'Sodium/.minecraft/saves"'

这不是你想要的,为什么错误信息说Sodium/.minecraft/saves"不存在。

正如@tkausl所评论的,解决方案是"${i}/.minecraft/saves"(或者不带括号的"$i/.minecraft/saves")。

这样,当i包含像:i="1.19 Sodium"这样的空格时,

ln -s saves "$i/.minecraft/saves"

被视为:

  • ln -s saves '1.19 Sodium/.minecraft/saves'
  • 或(同等)ln -s saves "1.19 Sodium/.minecraft/saves"
  • 或(同等)ln -s saves 1.19 Sodium/.minecraft/saves.

通过此更正,i中的任何空格将不再被解释为字段分隔符,因为i位于由双引号分隔的字符串中。

结论:永远不要使用没有引号的变量(即使echo "$i"而不是echo $i)。

最新更新