os.symlink
crea un solo enlace simbólico.
ln -s
crea múltiples enlaces simbólicos (si su último argumento es un directorio y hay más de una fuente). El equivalente de Python es algo como:
dst = args[-1]
for src in args[:-1]:
os.symlink(src, os.path.join(dst, os.path.dirname(src)))
Entonces, ¿cómo funciona cuando haces ln -s /home/guest/dir1/* /home/guest/dir2/
? Tu caparazón hace que eso funcione, convirtiendo el comodín en múltiples argumentos. Si tuvieras que exec
el ln
comando con un comodín, buscaría una sola fuente llamada literalmente *
en /home/guest/dir1/
, no todos los archivos en ese directorio.
El equivalente de Python es algo así como (si no le importa mezclar dos niveles e ignorar muchos otros casos:tildes, variables env, sustitución de comandos, etc. que son posibles en el 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)))
No puedes hacer eso con os.symlink
solo, ya sea como parte de él, porque no hace eso. Es como decir "Quiero hacer el equivalente a find . -name foo
usando os.walk
sin filtrar el nombre". O, para el caso, quiero hacer el equivalente a ln -s /home/guest/dir1/* /home/guest/dir2/
sin que el caparazón se englobe para mí".
La respuesta correcta es usar glob
o fnmatch
o os.listdir
más una expresión regular, o lo que prefieras.
no usa os.walk
, porque eso hace un recursivo caminata del sistema de archivos, por lo que ni siquiera está cerca del shell *
expansión.
*
es un patrón de extensión de shell, que en su caso designa "todos los archivos que comienzan con /home/guest/dir1/
".
Pero es el rol de tu shell expandir este patrón a los archivos con los que coincide. No el ln
de comando.
Pero os.symlink
no es un shell, es una llamada del sistema operativo; por lo tanto, no admite patrones de extensión de shell. Tendrás que hacer ese trabajo en tu guión.
Para hacerlo, puede usar os.walk
o os.listdir
. Como se indica en la otra respuesta, la llamada adecuada dependerá de lo que quieras hacer. (os.walk
no sería el equivalente de *
)
Para convencerse:ejecute este comando en una máquina Unix en su terminal:python -c "import sys; print sys.argv" *
. Verás que es el caparazón el que hace el emparejamiento.