2 puan yazan GN⁺ 2025-01-29 | 1 yorum | WhatsApp'ta paylaş
  • Otomasyon betiklerini ~/bin/ içine koyup çalıştırma akışında uv ve satır içi betik meta verileri kullanıldığında Python betiklerini daha hafif şekilde yönetmek mümkündür
  • ~/bin PATH içinde yer alıyorsa shebang satırını #!/usr/bin/env -S uv run --script olarak ayarlayarak dosya adını bir komut gibi çalıştırabilirsiniz
  • Bu yapılandırma, kabuğun önce uv run --script komutunu çalıştırmasını ve mevcut betik dosyasını argüman olarak iletmesini sağlar
  • uv, shebang satırını yok saydıktan sonra kalan içeriği normal bir Python dosyası gibi çalıştırır
  • chmod a+x {filname} ile çalıştırma izni verirseniz bunu bağımlılıkları otomatik yöneten basit bir Python komut satırı betiği olarak kullanabilirsiniz

uv’yi shebang olarak çalıştırma

  • İş otomasyonu için ~/bin/ dizininde birden fazla betik oluşturup kullanıyorum
  • ~/bin PATH içinde yer alıyorsa betikleri yalnızca dosya adıyla doğrudan çalıştırabilirsiniz
  • Bu durumda kullanılacak shebang şu şekildedir
#!/usr/bin/env -S uv run --script

Çalışma akışı ve izin ayarı

  • Yukarıdaki shebang, komut satırında uv run --script komutunu çalıştırır ve betik dosyasını argüman olarak iletir
  • uv, shebang satırını yok saydıktan sonra dosyanın kalan kısmını normal Python kodu olarak çalıştırır
  • Çalıştırmadan önce betiğe çalıştırma izni verilmelidir
chmod a+x {filname}
  • Kurulum tamamlandığında bağımlılıkları otomatik olarak yöneten basit bir Python komut satırı betiğini doğrudan çalıştırabilirsiniz

1 yorum

 
GN⁺ 2025-01-29
Hacker News yorumları
  • Bugün env -S’yi ilk kez öğrendim ve yazıdaki shebang’i görür görmez “Linux’ta çalışmaz; çünkü shebang yalnızca tek bir argüman geçirebilir” diye düşündüm.
    Örneğin #!/usr/bin/env -S uv run --script ile başlayan foo.py çalıştırıldığında işletim sistemi aslında tüm shebang satırını tek bir argüman olarak /usr/bin/env '-S uv run --script' foo.py gibi geçirir.
    Ama env içindeki -S, o dizgeyi yeniden birden çok argümana böldüğü için çalışır. Çok şık ve kullanışlı.

    • macOS’ta bu davranış aynı olmadığı için sinir bozucu: https://unix.stackexchange.com/a/774145
    • GNU Guile’ın tek argüman sınırını çok satırlı shebang ile ele alma yöntemi aklıma geldi.
      #!/usr/bin/guile \ satırından sonra gelen satıra -e main -s koyup !# ile kapatırsanız /usr/bin/guile -e main -s filename gibi olur.
      Bunu neden özellikle böyle yaptıklarını merak ediyorum. Muhtemelen env -S yakın zamanda eklenmişti ya da ilgilendikleri tüm platformlarda kullanılamıyordu.
      https://www.gnu.org/software/guile/manual/html_node/The-Meta-Switch.html
    • make’e benzeyen ama yapılandırma için YAML kullanan bir Go CLI’ı olan tusk ile bu yöntemi kullanmak iyi oluyor.
      Shebang olarak #!/usr/bin/env -s go run github.com/rliebz/tusk@latest -f koyup yorumlayıcı olarak interpreter: go run mvdan.cc/sh/v3/cmd/gosh@latest -s şeklinde Go shell’i olan gosh’u kullanıyorsunuz.
      Böylece yalnızca Go kuruluysa her mimaride çalışabilen bir CLI elde ediliyor.
    • Wrapper iş birliği yaparsa takip eden satıra daha fazla bilgi de koyabilirsiniz.
      Örneğin nix-shell, #!/usr/bin/env nix-shell satırından sonra #!nix-shell --pure -i runghc ./default.nix satırını koyarak bağımlılıkları ve argümanları belirtebilir; ardından Haskell kodunu yazmaya devam edebilirsiniz.
    • env -S’ye en başta ihtiyaç olmamalıydı.
      Shebang satırındaki tuhaf boşlukla ayırma kuralları, düzeltilemeyen eski bir hatanın Unix’in kalıcı bir kusuruna dönüşmüş hâli.
      Yukarıdaki gibi geçici çözümleri her kullandığımda, 1980’lerde buna 30 dakika ayrılsaydı sonraki yıllarca süren sinir bozukluğundan kaçınılabilirdi diye düşünüyorum. Shebang satırı en başından /bin/sh gibi ayrıştırılmalıydı.
  • Shebang değil ama son zamanlarda uv’yi kurulum aracı gibi kullanıyorum.
    Karmaşık bağımlılıkları olan Python CLI araçlarını paketlemek ve dağıtmak zor olduğu için iki şekilde yararlandım.
    Biri, curl | sh kurulum betiğini kopyalayıp sonuna uv tool install --python python3.12 my-tool ekleyerek kullanıcının CLI’ı tek satırla kurmasını sağlamak; diğeri ise yalnızca uv bağımlılığı olan küçük bir PyPI “kurucu” paketi oluşturup uv tool install çalıştırmasını sağlamak.
    İki yöntem de CLI aracını, Python 3.12’yi ve tüm Python bağımlılıklarını yalıtılmış bir ortama kuruyor. Kullanıcının sanal ortam yönetmesine gerek kalmıyor; curl | sh yönteminde Python’ın kurulu olması bile gerekmiyor.
    Bundan sonra kullanıcıların karmaşık bağımlılıkları bozmasından kaynaklanan GitHub issue’ları belirgin biçimde azaldı.
    Ayrıntılar ve kod bağlantısı: https://aider.chat/2025/01/15/uv.html

    • İçeride nasıl çalıştığını kontrol etmedim ama CLI aracıyla birlikte Python 3.12 kurulumu da yapıyorsa, son kullanıcı sisteminde derleyici, kernel header’ları, openssl-dev, gzip, ffi gibi kütüphane header’ları gerekmez ve Python’ı derlemek zorunda kalınmaz mı diye düşünüyorum.
      En azından ASDF-VM kullanırken, içerideki başka Python kurulum araçları yüzünden böyle bir deneyim yaşamıştım.
    • Güzel. mise ve aquada da yararlı bir araç kurulumu kavramı var gibi görünüyor.
  • İlginç shebang konusu açılmışken, Prolog .pl dosyalarını kabuktan çalıştırmak için şöyle bir şey yapmıştım
    /*usr/bin/env scryer-prolog "$0" "$@" ; exit #*/
    /**/ yorumları olan ama # yorumlarını ya da #! shebang’i doğrudan desteklemeyen betik dillerinde genel olarak çalışacak gibi görünüyor
    Orijinal yorum: https://github.com/mthom/scryer-prolog/issues/2170#issuecomment-1821713993
    Bu dosya hem geçerli bir shell dosyası hem de geçerli bir Prolog dosyası. Shell olarak çalıştırıldığında ilk satır glob deseni /*usr/bin/env ile /usr/bin/envyi bulup çalıştırıyor; env de scryer-prolog "test.pl"yi çalıştırıyor. Prolog tarafında ise ilk satır /* ... */ yorumu olduğu için yok sayılıyor
    Ardından shell, ; sonrasındaki exiti çalıştırarak geri kalan Prolog kodunun shell olarak yorumlanmasını engelliyor; # ise shell’in Prolog yorum kapatıcısı */yi yok saymasını sağlayıp hata çıktısını önlüyor
    Yaptığım şeyler arasında en iyisi ve en kötüsü olabilir

    • Benzer şekilde Go kaynaklarını çalıştırılabilir hâle getirmenin de bir yolu var: https://unix.stackexchange.com/questions/162531/shebang-starting-with
      Buna ek olarak C programları da //usr/bin/env sh -c ... biçimindeki bir ilk satır kullanılarak çalıştırılabilir hâle getirilebilir. Çalıştırma sırasında make ile derleyip ortaya çıkan ikiliyi çalıştırdığı için, kaynağı değiştirip yeniden çalıştırdığınızda değişen çıktı hemen görünür
    • Kendim bulmuş değilim ama TCL’de de buna benzer bir yöntem kullanılıyor
      #!/bin/sh satırının ardından # the next line restarts using tcl \ satırı konup exec tclsh "$0" "$@" çalıştırılacak hâle getirilebiliyor
      Bu, TCL’de yorum satırlarında da satır devamı yapılabilmesinden yararlanıyor
    • Bu gerçekten harika. Scryer’ın giriş/çıkış yönlendirmesi biraz düzeltilirse bash betiklerinin alternatifi olarak mükemmel olabilir
  • Trey Hunner’ın Lazy self-installing Python scripts with uv yazısında örneklerle birlikte daha ayrıntılı bilgi var
    https://treyhunner.com/2024/12/lazy-self-installing-python-scripts-with-uv/

    • Örnekler arasındaki “80 tane 0 yazdıran betik” shell’de de printf %.1s 0{1..80} $'\n' ya da for i in {1..80}; do echo -n 0; done; echo ile yapılabilir
      ffmpeg örneğinin de ffmpeg -i in.mp4 -c:v copy -filter:a volumedetect -pass 1 -f null /dev/null && ffmpeg -i in.mp4 -c:v copy -filter:a "loudnorm" -pass 2 out.mp4den ne farkı var pek anlayamadım
      Açıkçası Python tarafı daha karmaşık görünüyor
  • Küçük işler için bu püf noktasını mise (mise-en-place) ile birlikte kullanabilirsiniz: https://mise.jdx.dev/tasks/toml-tasks.html#shell-shebang
    tools içinde uv = 'latest' koyup, görevin run bloğunda #!/usr/bin/env -S uv run --script ve dependencies = ["requests<3", "rich"] tanımladıktan sonra Python kodunu ekleme yöntemi

  • 16 gün önce de ilgili bir yazı ve tartışma vardı: Uv's killer feature is making ad-hoc environments easy https://news.ycombinator.com/item?id=42676432 (502 puan, 417 yorum)

  • Akılda tutulmaya değer bir püf noktası
    Son zamanlarda Python takma adımı uv run python olarak değiştirdim ve oldukça rahat. .venv vb. yönetmeye gerek kalmıyor; sistem kurulumu ya da global/kullanıcı kurulumu sorunlarıyla da uğraşmıyorsunuz, Debian’da özellikle işe yarıyor
    Bir proje ya da ortam içinde REPL çalıştırırken de activate olmadan çağırabildiğiniz için düşünmeniz gereken şeyler azalıyor
    Ancak .py dosyasını uv ile doğrudan çağırırken proje/ortam dosyası yolu, .py dosyasının konumuna göre değil, mevcut çalışma dizinine göre belirleniyor; bu bir dezavantaj
    --project adlı açık bir seçenek var ve uv run --project /script.py gibi kullanılabiliyor; ama hedef dosyaya göre göreli bir proje seçeneği olsaydı tekrarı azaltacağı için iyi olurdu

  • uv veya uvxi komut çalıştırıcısı olarak kullanırken birkaç tuzakla karşılaştım, ama çoğu zaman iyi çalışıyor; çalıştığında da ciddi ölçüde zaman kazandırıyor
    Bir Python geliştiricisi ve meraklı biri olarak ev dizinim sığ klonlar ve tek seferlik test dizinleriyle dolu; bu tür yönetim yükünü azaltması gerçekten faydalı
    Bu fikri çalıp kullanmak istiyorum. .py olmayan ayrı bir uzantı mı kullandığını, yoksa .py dosyasında çalıştırma biti açık ve shebang bulunmasının, bunun sistem Python'ıyla değil doğrudan betik olarak çalıştırılabileceğinin işareti sayılıp sayılmadığını merak ediyorum

    • Son bir yıldır uv'yi tavsiye etmeye değer mi diye bizzat kullanıp tuzak listesini topluyordum; şaşırtıcı biçimde çok fazla değildi
      Sıfır değil, ama oldukça dikkatli arıyorum. Hangi tuzaklarla karşılaştığını öğrenebilirsem listeye eklemek isterim
    • Benim anladığım kadarıyla .py dosyasına çalıştırma biti ve yazıdaki shebang satırı eklenerek kullanılıyor
    • Hangi tuzaklar olduğunu gerçekten merak ediyorum
      Pipenv'de belirli bir bağımlılığın platforma göre farklı wheel'leri olduğunda sorun yaşanmıştı; Poetry'de ise düzgün çalışmıştı
      Pipenv'in kilit dosyası yalnızca kilitlenen platformun bağımlılıklarını içeriyordu, Poetry ise tüm platform varyantlarını kilit dosyasına ekliyordu
      uv'nin bu durumda nasıl davrandığına dair dokümanları henüz bulamadım
  • İşin özü şu
    Yakın zamanda yayımlanan bir PEP, Python betiklerinin başlangıç yorumlarında bağımlılıklarını nasıl bildireceğini tanımlıyor; uv ise bu bağımlılıkları tarayıp karşılayan ve ardından ilgili modüller içe aktarılabilir durumdayken betiği çalıştıran bir Python betik çalıştırıcısı ve paket yöneticisi
    Python betiğinin ilk satır yorumu olan shebang'de dosyayı python yerine uv ile çağıracak şekilde ayarlarsanız, betiği “çalıştırdığınızda” bu etkiyi otomatik olarak elde ediyorsunuz
    Sonuç olarak, kurulum gerektiren bağımlılıkları olan Python betikleri de doğrudan çalışıyor

    • Ancak $PATH içinde uv'nin kurulu olması gerekiyor
      Ayrıca uv bağımlılıkları kuracak olsa da, bu yöntemle Python yorumlayıcısını da otomatik kurup kurmadığı net değil
    • Sonuçta sisteme uv kurup tüm betiklerin başına bağımlılık satırını ekledikten sonra ancak “doğrudan çalışır” hale geliyor
      Kişisel olarak bunun eski usulle ortam oluşturup çağırmaktan zaman kazandırdığını düşünmüyorum
      uv'nin ortamı etkileşimli oturumlarda da yükleyip yükleyemediğinden, yoksa yalnızca betik çalıştırmak için mi kullanıldığından da emin değilim
  • TypeScript'i seviyorsanız aynı yaklaşımı Deno ile de kullanabilirsiniz. Bun ile de olur gibi, ama bizzat denemedim
    #! /usr/bin/env -S deno run şeklinde kullanılır; izin bayrakları gerekiyorsa #! /usr/bin/env -S deno run --allow-env --allow-read --allow-net gibi eklenebilir