Your code will fail for any filename that contains a space (e.g this one.txt) or on any system where the user name or group name contains spaces (a system joined to Active Directory, for example).
The construct for i in $(ls) should not be used. Instead, use a wildcard glob, for i in *.
Finally, in direct answer to your question about $(basename {}). The $( ... ) value is not protected from the shell with single-quotes, and so it is evaluated before the command is executed. The result of $(basename {}) is simply {} and therefore,
xargs -I% find ./my_dir -type f -name "%" -exec echo $(basename {}) \;
is parsed and executed as if you had typed this,
xargs -I% find ./my_dir -type f -name % -exec echo {} \;
You were probably looking for something like this
for i in *
do
find ./my_dir -type f -name "$i" -exec cp "$i" {} \; -quit
done
Don't forget that you should always double-quote your $ variables and expressions when you use them. (To be fair, it wouldn't have helped in this case, but it's something you need to get used to doing.)
$(basename {})with{}beforexargsstarts. There's probably a duplicate question somewhere. I know one on Super User.for i in $(ls). It is bad practice, likely to break, and is harder than the simpler and saferfor i in *.