Bir kabuk betiğinde bir takma ad nasıl çalıştırılır?


101

mpiexecTam yolu olan yürütülebilir bir dosyam var ~/petsc-3.2-p6/petsc-arch/bin/mpiexec. Bu komutu farklı dizinlerde yürütmek istediğimden (tüm yolu yeniden yazmak zorunda kalmadan), giriş dosyama bir takma ad yerleştiriyorum .bashrc:

alias petsc="~/petsc-3.2-p6/petsc-arch/bin/mpiexec"  

Bu mpiexeckomut yazarak kolayca bu dosyayı komut isteminde çalıştırmak için izin verir :

petsc myexecutable

scriptYeni takma adımı petsckomut olarak kullanarak adlandırılmış bir kabuk komut dosyası yazmaya çalıştım . Shell betiğime uygun izinleri verdikten sonra (kullanarak chmod) betiği çalıştırmayı denedim. Ancak, bana aşağıdaki hatayı verdi:

./script: line 1: petsc: command not found

mpiexecDosyaya tam yolu yazabileceğimi biliyorum , ancak her seferinde yeni bir komut dosyası yazmak istediğimde tam yolu yazmak çok zordur. Takma adımı petsckomut dosyası içinde kullanmamın bir yolu var mı ? Düzenleme yapmamın .bashrcveya .bash_profilebunun gerçekleşmesi için bir yol var mı ?


Takma adı eklemeye ne dersiniz .bash_aliases? Ayrıca, gibi göreceli yol yerine mutlak yolun takılmasına ne dersiniz?alias petsc='/home/user/petsc-3.2-p6/petsc-arch/bin/mpiexec'
Nitin Venkatesh

@nitstorm: Her iki çözüm de işe yaramaz gibi görünmüyor ... Hala eskisi gibi aynı hatayı alıyorum
Paul

Yanıtlar:


74
  1. Kabuk betiğinizde bir takma ad yerine tam yolu kullanın.

  2. Kabuk betiğinizde, değişken ve farklı bir sözdizimi ayarlayın

    petsc='/home/your_user/petsc-3.2-p6/petsc-arch/bin/mpiexec'
    
    $petsc myexecutable
  3. Komut dosyanızda bir işlev kullanın. petscKarmaşık ise muhtemelen daha iyi

    function petsc () {
        command 1
        command 2
    }
    
    petsc myexecutable
  4. Takma adlarınızı kaynaklayın

    shopt -s expand_aliases
    source /home/your_user/.bashrc

Muhtemelen .bashrcIMO'yu kaynaklamak istemezsiniz , ilk 3'lerden biri daha iyi olurdu.


16
shopt -s expand_aliasesAynı komut dosyasında kullanmadığınız sürece 4. Nokta çalışmaz .
enzotib

Öneriniz 2) işe yarıyor, ancak ilk satırı petsc = "..." yazmadan aynı komutu çoklu kabuk betiklerinde kullanabilmek istiyorum. Bunu yapmanın bir yolu var mı?
Paul

1
@enzotib - teşekkür ederim, cevabımı ekledim.
Panter

1
2. noktada, bir takma ad değil bir değişken belirlersiniz.
pabouk

1
OP tarafından talep edilmedi, ancak soru başlığı ile ilgili: 2. Nokta içeren komutlarla çalışmaz |. Burada kullanım shopt -s expand_aliasesve yerel takma ad, örneğin alias myalias='echo abc|rev'- kullanımdan önce satır sonu gerektirir (bkz. ALIASES in man bash). Nokta 4: Kaynaklanmış dosya etkileşimli olmayan yürütmeyi engelleyebilir, örneğin bir komut dosyasında. Erken arayın exitveya returnörneğin [ -z "$PS1" ] && return(birincil istemi etkileşimli olmayan bir kabuk belirten ayarlı değilse çek) ya da bir onay olabilir ide $-( $-kabuk seçeneklerini içerir, iinteraktif anlamına gelir). man bashBu değişkenler için bakınız .
geçerli

61

Diğer adlar kabuk işlevlerinin lehine kaldırılmıştır. Gönderen bashmanuel sayfa:

For almost every purpose, aliases are superseded by shell functions.

Bir işlev oluşturmak ve alt kabuklara dışa aktarmak için, aşağıdakini içine yerleştirin ~/.bashrc:

petsc() {
    ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
}
export -f petsc

Ardından komutunuzu komutlarınızdan serbestçe arayabilirsiniz.


Neredeyse işe yarıyor ... tek sorun, çalıştırılabilir "mpiexec" e farklı bayraklar aktarabilmem gerektiği ... Örneğin, "petsc -n 40 myexecutable" gibi bir şey çalıştırabilmem gerekiyor. takma ad "petsc"
Paul

4
@ Paul: "$@"Sadece argümanları işlemek için ekledim .
enzotib

12

Kabuk işlevleri ve diğer adları kabukla sınırlıdır ve yürütülen kabuk komut dosyalarında çalışmaz. Davanız için alternatifler:

  • (Kullanmak için zahmet yoksa mpiexecyerine petsc) ekleyin $HOME/petsc-3.2-p6/petsc-arch/binsizin için PATHdeğişken. Bu düzenleme ~/.profileve ekleyerek yapılabilir :

    PATH="$HOME/petsc-3.2-p6/petsc-arch/bin:$PATH"

    Bu değişiklikleri uygulamak için tekrar giriş yapın

  • Dizini oluştur ~/binve

    • petsciçeren adlı bir sarmalayıcı komut dosyası yapmak :

      #!/bin/sh
      exec ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
    • program izin veriyorsa, aşağıdaki komutu kullanarak shellscript'i atlayabilir ve bir link oluşturabilirsiniz:

      ln -s ~/petsc-3.2-p6/petsc-arch/bin/mpiexec ~/bin/petsc

9

Bash 4'te özel değişkeni kullanabilirsiniz: $BASH_ALIASES.

Örneğin:

$ alias foo="echo test"
$ echo ${BASH_ALIASES[foo]}
echo test
$ echo `${BASH_ALIASES[foo]}` bar
test bar

Alternatif olarak değişken olarak tanımlayın, sonra komut ikameini kullanın veya eval.

Yani, örneğin, takma adı tanımlamak yerine:

alias foo="echo test"

olarak tanımla:

foo="echo test"

yerine. Ardından ikisinden birini uygulayın:

find . -type f -exec sh -c "eval $foo" \;

veya:

find . -type f -exec sh -c "echo `$foo`" \;

Takma isimler kabuk fonksiyonlarının lehine itiraz edilse de, bu cevap kabul edilmesi gereken tek cevap. Eski Debian 8 bile bash sürüm 4'e sahip, yani ${BASH_ALIASES[alias]}güzel bir seçenek. Aksi takdirde, başka şeyler uygulamak için .bash_aliases satırlarımın çoğunu düzenlemek zorunda kaldım. Teşekkür ederim.
erm3nda

8

Bash komutunuzu -i bayrağıyla etkileşimli bir kabuk olarak çalıştırmaya zorlayabilirsiniz. Bu, .bashrc dosyasına takma adları ve diğer işlevleri tanımlamasını söyleyecektir .

Örnek:

~ $ grep ll .bashrc
alias ll='ls -lah'
~ $ cat script.sh 
#!/bin/sh

ll
~ $ bash script.sh 
script.sh: line 3: ll: command not found
~ $ bash -i script.sh
..directory contents..

Daha fazla bilgi:

$ man bash

2
.bashrcetkileşimli olmayan SSH komutunun yürütülmesi sırasında da okunur (bu yüzden en üstte etkileşimi kontrol eder)
muru

6
ALIASES
   ...
   Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see the description of shopt under SHELL BUILTIN COMMANDS
   below).

Dolayısıyla, bu sorunun asıl cevabı, kabuk takma komutlarında gerçek takma adları kullanmak yerine alternatifleri kullanmak isteyenler için:

#!/bin/bash

shopt -s expand_aliases

alias foo=bar

foo whatever

Neden bunu yapmak istediğime gelince : Alışılmadık koşullar nedeniyle, bir Docker dosyasını bir kabuk betiği olduğunu düşünmek için kandırmam gerekiyor.


4
  1. İçinde .bash_aliases:

    petsc {
    ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
    }

    Veya işlevi yerine koyun .bashrc. Genellikle .bashrcsadece yapılandırma ayarlarında bashsaklanır.

  2. Terminalde: source .bash_aliases

  3. Bunu aramak: petsc arg(s)

Avantajı: İhtiyacınız olmayan export -f petscyer .bash_aliases. Takma adlar kullanımdan kaldırılmıştır ancak .bash_aliasesişlevler için kullanımı tamamdır.


Bu çözümü beğendim, daha sonra deneyeceğim
Greenonline

2
  1. Takma adınızı kabuk betiğinizde kullanın.
  2. Komut dosyanızı yürütmek yerine geçerli, etkileşimli kabuğunuzda kaynaklayın.

Bu nedenle script.sh, diğer adların kullanılmasını içeren komutlarınızla birlikte adlandırılmış bir dosyanız varsa , şunu yazın:

source script.sh

@DavidFoerster Bu yöntem iyi çalışıyor. Bir komut dosyasını .veya sourcebuiiltin ile kaynaklamak mevcut kabuğun içindeki tüm komutları çalıştırmasına neden olur . Takma ad genişlemesi, içinde .veya sourceçalıştırıldığı kabukta gerçekleşirse, gerçekleşir. Bununla birlikte, bu yöntemin sadece bazen yararlı olduğunu anlamak önemlidir, çünkü çoğu zaman bir betiği kendi ortamında, kendi ortamı ile çalıştırmak ister. Her zamanki gibi yürütülmek üzere yazılan Shell scriptleri genellikle kaynak gösterilmemeli - çoğu zaman doğru çalışmayacaktır.
Eliah Kagan

@EliahKagan: Teşekkürler. Şimdi cevabın ne anlama geldiğini anladım. Bir açıklama ekleyeceğim.
David Foerster

1

(EDIT: mpiexec çağrısını yanlış çağırdığımdan beri işlevler kaldırıldı.)

İhtiyacınız olan tek şey daha az yazmaksa, klasörü neden $ PATH içine yazmıyorsunuz? Veya $ PATH içindeki bir klasördeki mpiexec ile bir link oluştur? Veya (en sevdiğim), diğer adı çağıran komut dosyasında kaynak yaptığınız bir komut dosyasına koymak?


1
Bunu $ PATH’e ekleyemememin nedeni $ PATH’imde başka bir dizinde başka bir 'mpiexec' dosyasına sahip olmam. Bu yeni 'mpiexec'e yolu eklersem, muhtemelen ikisini de çalıştırmayı deneyecek ... değil mi?
Paul

1
Neden sadece kullanmadığınızı anlayamıyorum "$@".
enzotib

2
Paul, her ikisini de değil, ilk PATH'de olanı çalıştırmayı deneyecek.
Hamacı

enzotib, ah mpiexec'in çağrılma şeklini yanlış anladım, hepsinin bir bütün olarak ihtiyaç duyduğunu düşündüm. Cevabımı düzenleyeceğim :)
Hamam
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.