Neden bash betiğimi çalıştırırken modülleri yükleyemiyorum, ama sadece kaynak yaparken?


13

Sistemimdeki paketleri kontrol etmek için modüller kullanıyorum ve python/2.7.2modül olarak kurdum. Ben python_exe.pybasit bir 'sürüş' komut dosyasından arayacağım basit python yürütülebilir var runit.sh. runit.shkomut dosyası şuna benzer:

#!/bin/bash
module load python/2.7.2
arg1=myarg1
arg2=15
arg3=$5
/path/to/python_exe.py -a $arg1 -b $arg2 -c $arg3

Ancak, ben sadece çalıştırdığımda ./runit.sh, bana "module: command not found" satıyor. Ne zaman source runit.shki, doğru modülü yükler. Bu neden?

Yanıtlar:


14

Çünkü modulekomut bir takma ad ya da kabuk fonksiyonudur (bakınız " paket başlatma bölgesindeki" modülü (1) ). Derken source runit.sh, bu yazarak gibi moduleetkileşimli kabuk doğrudan komut. Ancak, dediğinde ./runit.sh, etkileşimli olmayan yeni bir kabuk çalıştırıyorsun. Etkileşimli olmayan mermiler genellikle standart takma adlara ve kabuk işlevlerine sahip değildir.

modül (1) , “Kabuğa özel bir başlatma komut dosyası kabuk içine kaynaklandığında, Modüller paketi ve modül komutu başlatılır. Komut dosyası, modül adını, diğer ad veya kabuk işlevi olarak oluşturur,… ” moduleKomutu bir komut dosyasında çalıştırmanız gerekiyorsa, komutu tanımlayan başlatma komut dosyasını ve modulekomut dosyasından bulun source.


Bu .bashrc ve .bash_profile kullanma arasındaki fark mıdır? Modül sistemini kullanmak için başlatmak için bunlardan sadece biri başlatma rutinlerine sahiptir.
drjrm3

Ne istediğini tam olarak bilmiyorum. Ancak: bash varsayılan olarak aşağıdakileri yapar (bu eylemler seçeneklere göre geçersiz kılınabilir): bir giriş kabuğu `~ / .bash_profile` ~/.bashrcdeğerini okur , ancak bir giriş kabuğu olmayan etkileşimli bir kabuk (ör bash. bir komut) okur, ~/.bashrcancak okumaz ~/.bash_profileve etkileşimli olmayan bir kabuk (örn. bir komut dosyası çalıştıran bir kabuk) da okumaz. … (Devamı)
Scott

(Devam)… Muhtemelen bu yüzden Cyrus önerdi #!/bin/bash -i- çünkü -iseçenek kabuğu etkileşimli hale getiriyor ve bu nedenle de okunmasına neden olacak ~/.bashrc. IMHO, bu aşırıya kaçıyor, çünkü interaktif mod istenmeyen bagajlarla gelebilir (yazmak gibi ~/.bash_history). Öte yandan, modulebir takma ad olarak tanımlanırsa (kabuk işlevinin aksine), siz söylemedikçe etkileşimli olmayan bir kabukta çalışmaz shopt -s expand_aliases, bu yüzden belki de Cyrus'un cevabı en iyisidir.
Scott

4

Sisteminizdeki kabuğun basit bir şekilde çağrılması, tanımlanmış olan takma adı (veya işlevi) miras almaz module, bu nedenle kabuk onu bulamaz (alıntılarla birlikte notun altına bakın). Şu anda type modulenasıl moduletanımlandığını görmek için bilgi isteminden deneyin .

Temelde kaynak ile komut dosyasının her satırını klavyeden yazarsanız gibidir.
Bir tarafta geçerli kabuğun tüm geçmişini miras aldığınızı, ancak diğer tarafta geçerli kabuğun komut dosyanızın ve moduleçağrınızın tüm taraflarının etkisine maruz kalacağını unutmayın .

Hakkında bir senaryo kaynak ve çalıştırmak için arasındaki farklar Eğer SuperUser okuyabilirsiniz Eyl 2009 veya Ara 2009 , Ubuntu Şubat 2011 , Unix Ağustos 2011 , Stackoverflow Aralık 2012 veya birçok başka yerlerde.

Bu bağlamda Modulefiles bölümünde bir uyarı var :

... Bir modülün boşaltılması sırasında ortam değişkenleri ayarlanmamıştır. Böylece, bir modül yüklemek ve sonra ortam değişkenleri önceki durumlarına dönmeden boşaltmak mümkündür .

Bu yüzden bunu bir senaryoda yürütmek daha akıllıca görünüyor .

İkincisini başarmak için düşünebilirim:

  1. Bir kullanmak için etkileşimli kabuk , mevcut kabuğun belirli geçmişini ihmal değiştirerek, shebang senaryonuzun ile

    #!/bin/bash -i

    Etkileşimli kabuk, kullanıcı girişindeki komutları tty'de okur. Diğer şeylerin yanı sıra, böyle bir kabuk etkinleştirme sırasında başlangıç ​​dosyalarını okur, bir istem görüntüler ve varsayılan olarak iş kontrolünü etkinleştirir ...

  2. Bunun yerine mevcut kabuğun belirli bir hikayesini miras almayı tercih ederseniz, onu kaynaklamayı deneyebilirsiniz ... ancak bir alt kabukta

    ( source runit.sh )
  3. Mevcut takma / fonksiyon bulmaya çalışın moduleile type moduledaha sonra sonucu Senaryonu değiştirin. Bazı ortam değişkenleri için ayarlanamayacağını unutmayın module.
    İsterseniz, başlatma komut dosyalarını dizinde bulabilirsiniz $MODULESHOME/init/<shell>.


Yorum Modüllerin Soru ve Cevaplarında
hatırlandığı gibi

Bir alt işlem (komut dosyası), üst işlem ortamını değiştiremez. Bir komut dosyasındaki modül yükü yalnızca komut dosyasının ortamını etkiler. Bir betiğin mevcut ortamı değiştirebilmesinin tek yolu, onu geçerli sürece okuyan betiği kaynaklamaktır.

Bu nedenle, mevcut ortamı değiştirmek istemiyorsanız, shebang'ı (1) değiştirmeye veya komut dosyasını bir alt kabukta (2) kaynaklamaya çalışmanın daha iyi olduğunu düşünüyorum . Vakanın kullanılabilirliğinden tam olarak emin değilim (3).


Not Modüllerin
manuel ve açıklama sayfalarından alıntılar

moduleModüller paketinin kullanıcı arayüzüdür. Diğer modulead veya işlevmodulecmd programı yürütür ve kabuğun komutun çıktısını değerlendirmesini sağlar. İlk argüman modulecmdkabuk türünü belirtir.

Modüller paketi ve modulekomut , kabuğa özel bir kabuk başlatma komut dosyası kaynaklandığında başlatılır . Komut dosyası, bir takma ad veya kabuk işlevi olarak modül komutunu, Modüller ortam değişkenlerini oluşturur


Ancak ana sürecin ortamını etkilemeye çalışmamaktadır; sadece Python'unu senaryodan çalıştırmak için çalıştırmaya çalışıyor . Ayrıca cevabınız neden “module: command not found” hata mesajını aldığını açıklamıyor.
Scott

@Scott teşekkürler. Yanlışlıkla cevabın büyük kısmını kesip sadece bir parça yayınlamadan önce. Cevap yeniden yazıldı.
Hastur

1
+1.  ( source runit.sh )iyi bir cevaptır; Bunu düşünmemiştim. Ve iyi bir referans koleksiyonu.
Scott
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.