GNU/Linux >> Belajar Linux >  >> Linux

`os.symlink` vs `ln -s`

os.symlink membuat satu symlink.

ln -s membuat banyak symlink (jika argumen terakhirnya adalah direktori, dan ada lebih dari satu sumber). Setara dengan Python adalah sesuatu seperti:

dst = args[-1]
for src in args[:-1]:
    os.symlink(src, os.path.join(dst, os.path.dirname(src)))

Jadi, bagaimana cara kerjanya saat Anda melakukan ln -s /home/guest/dir1/* /home/guest/dir2/ ? cangkang Anda membuatnya berfungsi, dengan mengubah wildcard menjadi beberapa argumen. Jika Anda hanya exec ln perintah dengan wildcard, itu akan mencari satu sumber yang secara harfiah bernama * di /home/guest/dir1/ , tidak semua file di direktori itu.

Setara dengan Python adalah sesuatu seperti (jika Anda tidak keberatan menggabungkan dua level bersama-sama dan mengabaikan banyak kasus lain—tilde, variabel env, substitusi perintah, dll. yang dimungkinkan di 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)))

Anda tidak dapat melakukannya dengan os.symlink sendirian—baik bagian dari itu—karena tidak melakukan itu. Ini seperti mengatakan "Saya ingin melakukan yang setara dengan find . -name foo menggunakan os.walk tanpa memfilter namanya." Atau, dalam hal ini, saya ingin melakukan yang setara dengan ln -s /home/guest/dir1/* /home/guest/dir2/ tanpa shell globbing untuk saya."

Jawaban yang tepat adalah menggunakan glob , atau fnmatch , atau os.listdir plus regex, atau apa pun yang Anda suka.

Jangan jangan gunakan os.walk , karena itu merupakan rekursif sistem file berjalan, jadi bahkan tidak dekat dengan shell * ekspansi.


* adalah pola ekstensi shell, yang dalam kasus Anda menunjuk "semua file dimulai dengan /home/guest/dir1/ ".

Tapi itu peran shell Anda untuk memperluas pola ini ke file yang cocok. Bukan ln perintah.

Tapi os.symlink bukan shell, ini panggilan OS - karenanya, tidak mendukung pola ekstensi shell. Anda harus melakukannya dalam skrip Anda.

Untuk melakukannya, Anda dapat menggunakan os.walk , atau os.listdir . Seperti yang ditunjukkan pada jawaban lain, panggilan yang sesuai akan bergantung pada apa yang ingin Anda lakukan. (os.walk tidak akan sama dengan * )

Untuk meyakinkan diri sendiri:jalankan perintah ini pada mesin Unix di terminal Anda:python -c "import sys; print sys.argv" * . Anda akan melihat bahwa shell yang melakukan pencocokan.


Linux
  1. Waktu Habis Dalam Skrip Shell?

  2. Shell mana yang saya jalankan?

  3. Array Asosiatif Dalam Skrip Shell?

  1. Penguncian yang Benar Dalam Skrip Shell?

  2. Sejarah Hancur?

  3. Cara Mengganti Shell di Linux

  1. Menyesuaikan shell Bash

  2. Array Di Unix Bourne Shell?

  3. Ubah .txt menjadi .csv di shell