Bash betiğim neden takma adları tanımıyor?


216

Benim ~/.bashrcdosyamda iki tanım bulunur:

  1. commandA, daha uzun bir yolun diğer adıdır
  2. commandB, bir Bash komut dosyasının diğer adıdır

Aynı dosyayı bu iki komutla işlemek istiyorum, bu yüzden aşağıdaki Bash komut dosyasını yazdım:


#!/bin/bash

for file in "$@"
    do
    commandA $file
    commandB $file
done

Oturumumdan çıktıktan ve tekrar giriş yaptıktan sonra bile, Bash, command not foundbu betiği çalıştırdığımda her iki komut için de hatalar istiyor .

Neyi yanlış yapıyorum?


10
BTW, takma adın tanınması için giriş ve çıkış yapmanıza gerek yok. Sadece ihtiyacın var source ~/.bashrc.
— tshepang

Benim durumum için uzaktan SSH ajanı ile bağlandım, SSH ajanı kapanırken takma ad ekledikten sonra tekrar çalışmaya başladım.
— dav

Diğer ad, bir komutu kısaltmanın bir yoludur. (Yalnızca etkileşimli kabuklarda kullanılırlar, komut dosyalarında kullanılmazlar - bu, bir komut dosyası ile etkileşimli bir kabuk arasındaki çok az farktan biridir.)
— Kris Roofe

Yanıtlar:


117

Her şeyden önce, ddeimeke'nin dediği gibi, etkileşimli olmayan kabuklarda varsayılan olarak takma adlar genişletilmez.

İkincisi, ortam değişkenini .bashrcayarlamadığınız sürece etkileşimli olmayan kabuklar tarafından okunmaz BASH_ENV.

Ama en önemlisi: bunu yapma! Lütfen? Bir gün o betiği gerekli takma adların ayarlanmadığı bir yere taşıyacaksınız ve tekrar kırılacak.

Bunun yerine ortam değişkenlerini betiğinizde kısayol olarak ayarlayın ve kullanın:

#!/bin/bash

CMDA=/path/to/gizmo
CMDB=/path/to/huzzah.sh

for file in "$@"
do
    $CMDA "$file"
    $CMDB "$file"
done

5
Bu çözüm olağan aliaskullanım durumlarında işe yaramaz . Örn alias mv="mv -v --backup=numbered".
— Evi1M4chine

@ Evi1M4chine: Evet, öyle. En azından Gilles gereksiz düzenlemeye döndükten sonra. Ancak yine de parametreler için farklı bir değişken kullanmak daha iyi olabilir.

1
Ah dikkat eksikliği etrafında tırnak $CMDA/ $CMDB... dışında büyük değişkenlerden bash bash kendisi için ayrılmış olan ve gerçekten zaten ... tırnak eksikliğinin beni gerçekten rahatsız eden, teşekkürler çalışma.
— Evi1M4chine

@ Evi1M4chine: Uh, ne? 1. En son düzenlemede alıntıları kendim kaldırdım. 2. 'bash' için ayrılmış '' kelimesini nereden alıyorsunuz? Bu ilk duyduğum şey olurdu. Eğer 3. o huzursuz yapar, nasıl ilk etapta bash kullanarak hissettiriyor? Neyse, söylediğim gibi seçenekler için ayrı bir değişken kullanın.

1
@ Alvas: Varsayım gizmoyolda değil ya da aynı ada sahip fakat daha yüksek önceliğe sahip bir komut var. Başka basit kurulum olabilir CMDAdüz için gizmoilk etapta.

161

Bash manpage'e bakarsanız aşağıdakileri bulabilirsiniz:

Kabuk etkileşimli olmadığında, takma adlar genişletilmez, eğer ext_aliases kabuğu seçeneği shopt kullanılarak ayarlanmazsa (aşağıdaki SHELL BUILTIN KOMUTLARI altındaki shopt tanımına bakın).

Öyleyse bir

shopt -s expand_aliases

Komut dosyasında.

Komut dosyasında bunu ayarladıktan sonra takma adınızı kaynakladığınızdan emin olun.

shopt -s expand_aliases
source ~/.bash_aliases

7
Senaryomu yazdım ama hala çalışmıyor. Aynı hatayı.
— Zaid,

5
Eklemek shopt -s expand_aliases source ~/.bash_aliasesbenim için mükemmel çalışıyor. Genellikle # If not running interactively, don't do anything [ -z "$PS1" ] && return.bashrc'de şöyle bir etkileşimli kabuk algılama şekli vardır: @Zaid, Belki kaynakta bulunduğunuz dosyada bunu kontrol etmek istersiniz.
— Frank Schubert

1
mükemmel! senaryolarımı kurtardım !! :) çok uzun zaman önce vazgeçtiğim ve internette aramaya başladığım terminaldeki bilgi ve manpagesi okumak / aramak / taramak çok zor ...
— Aquarius Power

2
Merakla, shopt -s expand_aliasestakma ad tanımından önce değil, takma ad kullanmadan önce gitmek zorunda değildir. @FrankSchubert'e ekleme: $-Özellikle ikabuk etkileşimli ise, kabuk için seçenekleri içeren etkileşimli kabuk algılama da yapılabilir .
— geçerli

2
bu doğru bir cevap değil ... Takma adınızı komut dosyanızın içine almak cevap değildir. Sizin ~/.bash_aliasesdaha önce bir interaktif kabuk yüklenen diğer şeyler bağlı olabilir ... Ben buldum en yakın şey için hashbang değişiyor #!/bin/bash -limükemmel değildir Hala. İdeal olarak, takma adları değil işlevleri kullanmalısınız.
— Stefanos Kalantzis

44

Diğer adlar dışa aktarılamaz, bu nedenle tanımlanmadıkları kabuk komut dosyalarında kullanılamazlar. Başka bir deyişle, onları tanımlamak için ~/.bashrckullanılamazlar your_script.sh( ~/.bashrckomut dosyasında kaynak bulmadığınız sürece , bunu tavsiye etmem ama bunu doğru şekilde yapmanın yolları vardır).

Bununla birlikte, işlevler dışa aktarılabilir ve tanımlandıkları bir ortamdan çalıştırılan komut dosyalarını kabuklamak için kullanılabilir. Bu, bashrc'nize yerleştirerek yapılabilir:

varsayılan değer()
{
    yankı "Merhaba Dünya!"
}
ihracat-f foo

Bash el kitabının dediği gibi, "Neredeyse her amaç için, kabuk işlevleri takma adlara göre tercih edilir."


1
Bu teknik olarak soruya cevap vermez iken, sadece yerini alabilir söylediği gibi alias commandA=...ile commandA() { ... }daha sonra export commandAve takma isimle aynı davranışı olsun. Bu, bash
— betiğinde

Buradaki sorun, çok fazla alıntılanmış seçeneğin geçtiği bir diğer adaya ihtiyacınız olduğunda. örneğin bir örnek olarak, işlevlerde yapılması zor olan işlerin yapılmasını alias b=bashkolaylaştırır b -c "echo test | grep test".
— Fmstrat

@Fmstrat: b () { bash "$@"; }o zamanb -c "echo test | grep test"
— Dennis Williamson,

11
[cmd line] > bash -i [your script's file path]

iEtkileşimli içindir ve kaynakları bashsizin için profil.


-5

Bazen bash betiğinin de dışa aktarmayı tanımadığını öğrendim. Ancak, onu değiştirerek

#!/bin/sh

benim için çalışıyor.


1
Hayır, olmadı ...
— Hafiz Temuri
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.