问题
I am trying to use the output from mdfind
to create a bunch of symlinks. Output of mdfind
is like this:
/pathtofile1/
/pathtofile2/
/pathtofile3/
So, I used sed
to add ln -s
to the start of each line, and awk {print $0 "/directory where I want this/"}
;
after my single-line script successfully outputs 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"
Problem is, when I run this, I get this error: "/directory where I want this: File does not exist"
The weird thing is that when I run these lines individually, they links are created as expected, but running the entire command returns the error above.
Any ideas?
I don't think that this is the ideal way to do what I'm trying to do, so let me know if you have any better solutions.
Edited with more information.
#! /bin/bash
itemList=`mdfind -s "$1"| awk '{ print "ln -s \""$0"\" \"/Users/username/Local/Recent\""}'`
echo "$itemList"
`$itemList`
$1 is a test *.savedSearch that returns a list of files.
My result (from the echo) is:
ln -s "/Users/username/Dropbox/Document.pdf" "/Users/username/Local/Recent"
ln -s "/Users/username/Dropbox/Document2.pdf" "/Users/username/Local/Recent"
and the error that I get is:
ln: "/Users/username/Local/Recent": No such file or directory
But, if I run a copy-pasted of each line individually, the links are created as expected.
回答1:
One way to keep it simple:
mdfind -0 "query" | ( cd "/Users/username/Local/Recent" ; xargs -0 -I path ln -s path . )
This is of course doesn't handle duplicate file names, etc.
EDIT:
The reasons your solution is failing is that, first, the contents of $itemList
is being executed as one long command (i.e. the line feeds output by awk are ignored), and then, second, the command substitution occurs before quote removal. What is actually processed is roughly equivalent to:
ln '-s' '"/pathtofile1/"' '"/to"' 'ln' '-s' '"/pathtofile2/"' '"/to"' 'ln' '-s' '"/pathtofile3/"' '"/to"'
/bin/ln
recognizes this as the:
ln [-Ffhinsv] source_file ... target_dir
form of the command and checks to see that the final parameter is an existing directory. That test fails because the directory name includes the surrounding quote marks. Note carefully the error message you report and compare:
$ 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
So the morals of the story are, when you are dealing with file names in a shell, the safest solution is to avoid shell processing of the file names so you don't have to deal with quoting and other side effects (which is a big advantage of an xargs
solution) and keep it simple: avoid constructing complex multi-line shell commands. It's too easy to get unexpected results.
回答2:
It would be much easier to determine what the problem was if you used some actual, or at least plausible, paths as examples, but ln isn't going to create these directories for you if that's what you want.
来源:https://stackoverflow.com/questions/1930437/mdfind-used-for-creating-symlinks-not-working-as-expected