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.