du
will generally only count a hard linked file once, so du -sk some/directory
should work fine.
# ls -li
total 2048
131346 -rw-r--r-- 2 root root 1048576 Mar 6 13:12 file1
131346 -rw-r--r-- 2 root root 1048576 Mar 6 13:12 file2
# du -sk file1
1024 file1
# du -sk file2
1024 file2
# du -sk .
1028 .
The extra 4k is for the directory itself, but note that it does not claim that 2M is used by this directory...
As you observe, though, this will not take into account hard links that are outside your target. There's probably not an easy way around this without writing a script that walks the entire directory hierarchy to find all the other links to a file... du
will report an upper bound, though - you will get back some amount of space that is less than or equal to what du
reports.