os.symlink
creates a single symlink.
ln -s
creates multiple symlinks (if its last argument is a directory, and there's more than one source). The Python equivalent is something like:
dst = args[-1]
for src in args[:-1]:
os.symlink(src, os.path.join(dst, os.path.dirname(src)))
So, how does it work when you do ln -s /home/guest/dir1/* /home/guest/dir2/
? Your shell makes that work, by turning the wildcard into multiple arguments. If you were to just exec
the ln
command with a wildcard, it would look for a single source literally named *
in /home/guest/dir1/
, not all files in that directory.
The Python equivalent is something like (if you don't mind mixing two levels together and ignoring a lot of other cases—tildes, env variables, command substitution, etc. that are possible at the shell):
dst = args[-1]
for srcglob in args[:-1]:
for src in glob.glob(srcglob):
os.symlink(src, os.path.join(dst, os.path.dirname(src)))
You can't do that with os.symlink
alone—either part of it—because it doesn't do that. It's like saying "I want to do the equivalent of find . -name foo
using os.walk
without filtering on the name." Or, for that matter, I want to do the equivalent of ln -s /home/guest/dir1/* /home/guest/dir2/
without the shell globbing for me."
The right answer is to use glob
, or fnmatch
, or os.listdir
plus a regex, or whatever you prefer.
Do not use os.walk
, because that does a recursive filesystem walk, so it's not even close to shell *
expansion.
os.symlink
is a mere wrapper of the respective system call (well, more or less) and therefore wouldn't provide the same semantics you get from a full-fledged utility using that system call. – Margueriteos.symlink
" requirement? If the right thing to do is afor
loop over aglob
, why don't you want to do the right thing? – Odontoblastos.symlink
. I thought it would provide everythingln -s
does, but turns out it does not. – Ridln -s
does, it's something the shell does. – Odontoblastsymlink
,symlinkat
, orCreateSymbolicLinkW
. And the semantics are clearly designed to match POSIXsymlink
even if that's not what it ends up using. – Odontoblast