0

我正在尝试使用输出mdfind来创建一堆符号链接。的输出mdfind是这样的:

/pathtofile1/
/pathtofile2/
/pathtofile3/

所以,我曾经sed添加ln -s到每行的开头,并且awk {print $0 "/directory where I want this/"};

在我的单行脚本成功输出后:

ln -s "/pathtofile1/" "/directory where I want this"
ln -s "/pathtofile2/" "/directory where I want this"
ln -s "/pathtofile3/" "/directory where I want this"

问题是,当我运行它时,我得到这个错误:“/我想要的目录:文件不存在”

奇怪的是,当我单独运行这些行时,它们的链接按预期创建,但运行整个命令会返回上述错误。

有任何想法吗?

我认为这不是做我想做的事情的理想方式,所以如果你有更好的解决方案,请告诉我。


编辑了更多信息。

#! /bin/bash
itemList=`mdfind -s "$1"| awk '{ print "ln -s \""$0"\" \"/Users/username/Local/Recent\""}'`
echo "$itemList"
`$itemList`

$1 是一个测试 *.savedSearch,它返回一个文件列表。

我的结果(来自回声)是:

ln -s "/Users/username/Dropbox/Document.pdf" "/Users/username/Local/Recent"
ln -s "/Users/username/Dropbox/Document2.pdf" "/Users/username/Local/Recent"

我得到的错误是:

ln: "/Users/username/Local/Recent": 没有那个文件或目录

但是,如果我单独运行每行的复制粘贴,则链接会按预期创建。

4

2 回答 2

1

一种保持简单的方法:

mdfind -0 "query" | ( cd "/Users/username/Local/Recent" ; xargs -0 -I path ln -s path . )

这当然不处理重复的文件名等。

编辑:

您的解决方案失败的原因是,首先, 的内容$itemList作为一个长命令执行(即 awk 输出的换行符被忽略),其次,命令替换发生在引号删除之前。实际处理的大致相当于:

ln '-s' '"/pathtofile1/"' '"/to"' 'ln' '-s' '"/pathtofile2/"' '"/to"' 'ln' '-s' '"/pathtofile3/"' '"/to"'

/bin/ln认为这是:

ln [-Ffhinsv] source_file ... target_dir

命令的形式,并检查最后一个参数是否为现有目录。该测试失败,因为目录名称包含引号。仔细记录您报告和比较的错误消息:

$ ln a b c "/Users/username/Local/Recent"
ln: /Users/username/Local/Recent: No such file or directory
$ ln a b c '"/Users/username/Local/Recent"'
ln: "/Users/username/Local/Recent": No such file or directory

所以这个故事的寓意是,当你在 shell 中处理文件名时,最安全的解决方案是避免文件名的 shell 处理,这样你就不必处理引用和其他副作用(这是一个很大的问题)解决方案的优势xargs)并保持简单:避免构建复杂的多行 shell 命令。太容易得到意想不到的结果。

于 2009-12-18T23:37:35.830 回答
0

如果您使用一些实际的或至少合理的路径作为示例,那么确定问题所在会容易得多,但是如果您想要的话,ln 不会为您创建这些目录。

于 2009-12-18T22:13:56.013 回答