Betiğim bash veya tire tarafından çalıştırılıp çalıştırılmadığını nasıl belirleyebilir?


13

İki farklı sistemde yeni bir Oneiric yüklemesi (yani yükseltme değil) çalıştırıyorum ve görünüşte ilgili sorunlar kümesine koşuyorum.

Grubun en sinir bozucu yanı, Mac OS X'ten benimle taşıdığım .profile ve .bashrc'yi kullandığımda, LightDM aracılığıyla X'e giriş yapmak derhal oturumumu kapatıyor. Bunun, "/ bin / sh" çalıştırırken, / bin / dash olarak davrandığına, ancak yine de $ SHELL değişkeninin / bin / bash olarak ayarlanmış olmasından kaynaklandığına inanıyorum.

ekstrapolasyon

Çok kocam var .bashrc. İsterseniz burada görebilirsiniz , ancak içeriği bashisms ile dolu olması ve xterm içinde veya sanal bir konsolda hatasız çalışmasının yanı sıra muhtemelen ilgili değildir.

Benim .profileşöyle görünüyor (kısaltılmış):

case $SHELL in 
*bash*)
    if [ -f $HOME/.bashrc -a -r $HOME/.bashrc ]; then
        . $HOME/.bashrc
    fi
    ;;
esac

X'e LightDM üzerinden giriş yapmaya çalışırsam, hemen oturumumu kapatır. .xsession-errorsBu (kısaltılmış) gibi görünen benim .bashrc ile ilgili hatalar alıyorum:

/home/mrled/.bashrc: 103: [[: not found
[: 103: Linux: unexpected operator
[: 274: -P :: unexpected operator
/home/mrled/.bashrc: 520: complete: not found

Dediğim gibi, bash'ı sanal bir konsoldan çalıştırdığımda, bu hataları almıyorum. Ayrıca, .profile'ımı kaldırırsam, X'e iyi giriş yapabilirim. (Ayrıca sanal bir konsola giriş yapabilir ve startxçalışan bir X oturumu başlatmak için kullanabilirim , ancak bu elbette uzun vadeli bir çözüm değil.)

Ancak, ben çalıştırırsanız keşfetti /bin/sh -l, ben do hataları olsun. İşte bir örnek oturum (not: basitleştirdiğim bash istemi bash>ve sh istemi sadece $):

bash> echo $SHELL
/bin/bash
bash> echo $BASH_VERSION
4.2.10(1)-release
bash> /bin/sh -l
/home/mrled/.bashrc: 103: [[: not found
[: 103: Linux: unexpected operator
[: 274: -P :: unexpected operator
/home/mrled/.bashrc: 520: complete: not found
$ echo $SHELL
/bin/bash
$ echo $BASH_VERSION

$

S1: Bu neden oluyor?

/ Bin / sh'ın şimdi bash yerine tire işaret ettiğini anlıyorum , ancak bu doğruysa, neden $SHELLhala geri dönüyor /bin/bash?

S2: Etrafında çalışmak için ne yapabilirim?

Bu sorunu çözmek için bir yol var mı? Hem giriş hem de giriş olmayan kabuklarda aynı ortamı elde etmek için profilimi .bashrc yüklemeye devam etmek istiyorum, ancak açıkçası sadece bash için değil, bash için masquerading değil, bash için yüklenmesini istiyorum.

Yukarıdaki $ BASH_VERSION değişkeninin içeriğindeki farkı fark etmiş olabilirsiniz. Benim .profile böyle bir şey sarma denedim:

if [ -n $BASH_VERSION ]; then
    # the rest of my .profile as above
fi

-nDize uzunluğu sıfırdan yalnızca altında koşuyorum zaman testi, yukarıda oturumda olsa bile, ancak, gerçek dönmelidir /bin/sh -lbuna böyle benim .profile dahildir? $ BASH_VERSION için boş bir dize döndürür , testi geçer! Onlar benim .bashrc kaynak ve bana önceki gibi aynı hataları vermek için ilerler.

Şimdi gerçekten kafam karıştı.


Bu değere sahip olduğunu dash -lda gösterir . $SHELL/bin/bash
Scott Severance

3
$SHELL/etc/passwd(veya getent passwd) içindeki son alan ne derse desin.
sonraki duyuruya kadar duraklatıldı.

@DennisWilliamson Teşekkür ederim , doğru cevabı bulmak için bilmem gereken şey buydu.
Micah R Ledbetter

Yanlış yapıyorsun. Bash'a özgü olmayan bir ortam ~/.profile, bash'a özgü şeyleri içine koymalı ~/.bashrcve her ~/.bash_profileikisine de kaynak sağlamalısınız .
nyuszika7h

Yanıtlar:


12

İşinizde $BASH_VERSIONboş olan gerçeği dashsizin için yapabilirsiniz:

if [ "$BASH_VERSION" = '' ]; then
    echo "This is dash."
else
    echo "This is bash."
fi

2
"X" tekniği arkaiktir ve sadece eski mermilerde gereklidir . Kullanımif [ "$BASH_VERSION" = '' ]
sonraki duyuruya kadar duraklatıldı.

@DennisWilliamson: Teşekkürler. Tekniğinizin Bash'a özgü olduğunu düşünmüştüm, ama sadece Dash'e dayandım ve işe yaradı. Cevabımı düzenledim.
Scott Severance

Ya da sadece kullanın-n ya da hiçbir şey . (+1, yine = ''de. Mükemmel çalışıyor.)
Eliah Kagan

5

Sadece değişkeni tırnak kullanmak zorunda BASH_VERSIONkullanımına-n

if [ -n "$BASH_VERSION" ];then
 echo "this is bash"; 
else 
 echo "this is dash";
fi

1
çünkü [ "$EMPTY_STRING" ]değerlendirir yanlış, hatta gerek yok -n. Sadece değişkeni alıntılamak zorundasınız.
Ocak

2

Kullanım /proc/[PID]/cmdlinekomut dosyası içerdiği için ne ile ve test çalıştırılıyor görmek için. $$Değişken bize çalışan kabuğun PID verecektir. Böylece böyle bir senaryo yapabiliriz,

#!/bin/bash
if grep -q 'bash' /proc/$$/cmdline ;
then
    echo "This is bash"
else
    echo "This is some other shell"
fi

İşte aynı komut dosyasının bir testi:

$> bash test_script.sh                                                                                                
This is bash
$> dash test_script.sh                                                                                                
This is some other shell

Bu Mac'te çalışmaz. $ BASH_VERSION adresini kontrol edin.
Austin Burk

2
@AustinBurk Mac üzerinde çalışmasına gerek yok. Bu Ask Ubuntu.
TheWanderer

@ Zacharee1 oh lanet olsun, dikkat etmiyordum:,)
Austin Burk

Bunu istediğin şeyden uzakta düzenlemek istemiyorum, ancak bu yöntemin sınırlamalarından bahsetmeni öneririm. Bash'ın adına ihtiyacı yoktur bash; bashyürütülebilir dosyanın başka bir ada sahip bir symlink üzerinden çalıştırılması nadir değildir . Genellikle kişi hala Bash'i düşünmek ister. Ayrıca, desen edilir eşleşti yerde de/proc/$$/cmdline düzeltme mümkün, ama içinde argümanlar olduğunu akılda tutmak gereken, cmdlineboş karakter ayrılmış bulunmaktadır. grep -qE '(^|/)bash$'çalışması gerektiği gibi hissettirir, ancak herhangi bir argüman olduğunda yanlış pozitif verir bash.
Eliah Kagan

@EliahKagan Yanıtlarımı istediğiniz zaman düzenlemekten çekinmeyin - düzenlemelerinizin yalnızca iyileştirmeler sunabileceğini bilmek için yeterli uzmanlığa sahipsiniz. Cevap, kabuklarım şu anda olduğundan daha yeşil olduğunda yazılmıştır.
Sergiy Kolodyazhnyy
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.