Bash 为什么'ln-s**.txt'抱怨目标不是Linux中的目录?

Bash 为什么'ln-s**.txt'抱怨目标不是Linux中的目录?,bash,wildcard,symlink,Bash,Wildcard,Symlink,我需要对文件夹中的所有文件进行符号链接,而不重复添加扩展名到符号链接,我可以使用精确的引用,但不能使用通配符 root@os:~/test# touch {a..z} root@os:~/test# ls a b c d e f g h i j k l m n o p q r s t u v w x y z root@os:~/test# ln -s a a.txt root@os:~/test# ls a a.txt b c d

我需要对文件夹中的所有文件进行符号链接,而不重复添加扩展名到符号链接,我可以使用精确的引用,但不能使用通配符

root@os:~/test# touch {a..z}

root@os:~/test# ls
a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z

root@os:~/test# ln -s a a.txt

root@os:~/test# ls
a  a.txt  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z

root@os:~/test# ln -s * *.txt
ln: target 'a.txt' is not a directory

shell只是将全局表达式(星星)扩展为命令的参数。所以ln会得到参数a b c d e f g。。。和*.txt,因为不存在具有txt扩展名的文件。 但是ln希望你做的事情有两个论点。详情见曼恩

您试图完成的工作与循环有关:

假设您的shell是bash,您可以执行以下操作:

for i in *; do ln -s "${i}" "${i}.txt"; done
请记住,如果再次调用,所有txt链接也将再次进行符号链接

如果在脚本中使用该行,最好检查文件是否确实存在,否则将向命令提供globbing模式

差不多

for i in *.csv; do
    [ -f "${i}" ]  || continue
   # do something with ${i}
done

通配符扩展到当前目录中与给定模式匹配的所有文件名。在您的示例中,*匹配a、a.txt、b、…、z,*.txt匹配a.txt,因此展开后,您的命令如下所示:

ln-SAA.TXTBC。。。zA.txt

这是ln see的第三种形式,它要求它的最后一个参数是目录,因此出现了错误


您可以按照评论中的建议使用。

for i in*;do ln-s$i$i.txt;Donebeln需要2个参数,你要传递27个。思考一下*的含义。在命令行中键入带有*.globbings的echo通常会有帮助,只是为了看看它匹配什么。请注意,有关UNIX工具如何工作的问题只属于这里,而不属于这里-堆栈溢出仅用于有关编写代码的问题。@CharlesDuffy我同意,但这是一个非常接近的问题。如果把它放在脚本中,我想也没问题。我想循环是我的问题,因为多次运行它会得到多个符号链接文件,比如a.txt、a.txt.txt和a.txt.txt等。。。单个文件上的ln将返回void,因为它已经存在。请注意中的“问题解答”部分,以及其中最后一个要点,要求问题与软件开发有关。哦,我明白了,因此,它也会创建a.txt.txt.txt,即使它以我希望的方式处理-非常感谢@yjay的解释,他没有意识到这一点。抱歉没有发布到正确的位置。