Dir2内のdir1(ファイルまたはディレクトリ)のすべてのアイテムにシンボリックリンクを作成する必要があります。 dir2は既に存在し、シンボリックリンクではありません。 Bashでは、これを簡単に実現できます。
ln -s /home/guest/dir1/* /home/guest/dir2/
しかし、python using os.symlink
では、エラーが発生します。
>>> os.symlink('/home/guest/dir1/*', '/home/guest/dir2/')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 17] File exist
subprocess
を使用してln
コマンドを実行できることを知っています。私はその解決策が欲しくありません。
os.walk
またはglob.glob
を使用した回避策も可能であることを認識していますが、os.symlink
を使用してこれを実行できるかどうかを知りたいと思います。
os.symlink
は、単一のシンボリックリンクを作成します。
ln -s
は、複数のシンボリックリンクを作成します(最後の引数がディレクトリであり、複数のソースがある場合)。 Python同等のものは次のようなものです:
dst = args[-1]
for src in args[:-1]:
os.symlink(src, os.path.join(dst, os.path.dirname(src)))
では、ln -s /home/guest/dir1/* /home/guest/dir2/
を実行するとどのように機能しますか?あなたのShellは、ワイルドカードを複数の引数に変換することで機能します。ワイルドカードを使用してexec
コマンドだけをln
すると、*
という名前の単一のソースがそのディレクトリ内のすべてのファイルではなく、/home/guest/dir1/
で検索されます。
Pythonに相当します(2つのレベルを混合し、シェルで可能なチルダ、環境変数、コマンド置換など、他の多くのケースを無視してもかまわない場合) ):
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)))
os.symlink
だけでは(その一部でも)それを行うことはできません。 「名前でフィルタリングせずにfind . -name foo
を使用してos.walk
と同等の処理を行いたい」と言っているようなものです。または、そのことに関しては、Shellが私のためにグロブすることなく、ln -s /home/guest/dir1/* /home/guest/dir2/
と同等のことをしたいです。」
正解は、glob
、fnmatch
、またはos.listdir
に正規表現を加えたもの、または任意のものを使用することです。
notはos.walk
を使用します。これはrecursiveを行うためですファイルシステムウォークなので、Shell *
展開にも近くありません。
*
はシェル拡張パターンです。この場合、「/home/guest/dir1/
で始まるすべてのファイル」を指定します。
しかし、それはこのパターンを展開するシェルの役割一致するファイルです。 ln
コマンドではありません。
ただし、os.symlink
はシェルではなく、OS呼び出しです。したがって、シェル拡張パターンをサポートしていません。スクリプトでその作業を行う必要があります。
そのためには、os.walk
、またはos.listdir
を使用できます。他の回答に示されているように、適切な呼び出しは、何をしたいかによって異なります。 (os.walk
は*
と同等ではありません)
納得させるには:端末のUnixマシンでpython -c "import sys; print sys.argv" *
というコマンドを実行します。マッチングを行っているのはシェルであることがわかります。
@abarnertが示唆するように、*
を認識し、dir1内のすべてのアイテムで置き換えるのはシェルです。したがって、os.listdir
を使用することが最良の選択だと思います。
for item in os.listdir('/home/guest/dir1'):
os.symlink('/home/guest/dir1/' + item, '/home/guest/dir2/' + item)