Znajdowanie domyślnej powłoki użytkownika w skrypcie powłoki

10

Zastanawiałem się, czy w skrypcie powłoki można znaleźć domyślną powłokę bieżącego użytkownika?

Przypadek użycia: Pracuję nad skryptem, który ustawia alias dla polecenia, a ten alias jest ustawiony w skrypcie powłoki.

!# /bin/bash
alias = 'some command to set the alias'

W skrypcie jest logika, w której próbuje on znaleźć domyślną powłokę użytkownika, który wykonuje skrypt i dodaje ten alias do odpowiedniego pliku ~ / .bashrc lub ~ / .zshrc

Ale kiedy dodałem shebang na początku skryptu i wyraźnie prosiłem go o użycie basha, odpowiedzi zamieszczone tutaj zawsze zwracają bash zgodnie z oczekiwaniami, chociaż wykonuję ten skrypt na terminalu ZSH.

Czy istnieje sposób na uzyskanie typu powłoki, w którym skrypt jest wykonywany, niezależnie od zestawu shebang?

Szukam rozwiązania, które działa zarówno na Macu, jak i na wszystkich bistro opartych na systemie Linux.

Hiszpan89
źródło
@StephenRauch Powinienem o tym wspomnieć wcześniej, szukam metody, która działa zarówno na systemie Mac, jak i Linux. / etc / passwd na Macu nie zawiera informacji o użytkowniku i jest sprawdzany tylko w trybie pojedynczego użytkownika.
Hiszpan89
Co /etc/passwdma na OSX? Rzuciłem okiem w Internecie i wygląda na to, że jest tam powłoka, ale nie nazwa użytkownika. Identyfikator użytkownika wciąż tam jest, dlaczego tego nie użyjesz?
terdon
Zastanawiam się, czy w ogóle można mieć wyczerpującą listę pocisków. Czy też wszystkie pliki startowe powłoki zawsze są zgodne. {Name_of_shell} rc?
jamesqf

Odpowiedzi:

6
$ finger $USER|grep -oP 'Shell: \K.*'
/bin/mksh
Ipor Sircer
źródło
Dzięki, działa jak urok! To jedyne rozwiązanie, które prawdopodobnie działa zarówno dla bistro opartego na systemie Mac, jak i Linux.
Hiszpan89
1
BTW, trochę zmodyfikowałem to polecenie, aby było agnostyczne dla wszystkich systemów operacyjnych, finger $USER | grep 'Shell:*' | cut -f3 -d ":"ponieważ opcje grep -P nie są obsługiwane na Macu.
Hiszpan89
2
Uwaga: fingermoże nie być zainstalowany na wszystkich komputerach. Jest to opcjonalny pakiet w systemach opartych na RedHat.
Stephen Harris
1
@Kishorepandey: możesz użyć getent|grep ^$USER:|cut -f: -f7zamiast palca, jeśli palec nie został zainstalowany domyślnie.
Ipor Sircer
@Kishorepandey Nie rób tego. Użyj SHELLzmiennej środowiskowej, jeśli jest obecna. Spojrzenie na bazę danych użytkownika da wynik (powłoka logowania użytkownika), ale może nie być to właściwy wynik (ulubiona interaktywna powłoka użytkownika) - zależy to od konfiguracji użytkownika.
Gilles „SO- przestań być zły”
19

Zmienna środowiskowa SHELLzawsze rozwija się do domyślnej powłoki logowania użytkownika wywołującego (pobiera wartość z /etc/passwd).

Dla każdego innego użytkownika musisz wykonać pewne przetwarzanie /etc/passwd, oto prosty awkfragment:

awk -F: -v user="foobar" '$1 == user {print $NF}' /etc/passwd

Zastąp foobarrzeczywistą nazwą użytkownika.

Jeśli masz ldap(lub coś podobnego na miejscu), użyj, getentaby uzyskać bazę danych zamiast bezpośredniego analizowania /etc/passwd:

getent passwd | awk -F: -v user="foobar" '$1 == user {print $NF}'

lub najczystsze podejście, getentparsujmy (dzięki @Kusalananda):

getent passwd foobar | awk -F: '{print $NF}'
heemayl
źródło
3
getent passwd foobarpominąć konieczność dopasowania do określonej linii.
Kusalananda
Dziękuję za odpowiedź. Powinienem był o tym wspomnieć wcześniej, szukam metody, która działa zarówno w systemie Mac, jak i Linux. / etc / passwd na Macu nie zawiera informacji o użytkowniku i jest sprawdzany tylko w trybie pojedynczego użytkownika.
Hiszpan89
4

Ponieważ getentnie jest to standardowe polecenie w systemie MacOS, możesz skorzystać z getpwuidwywołania niższego poziomu , które skonsultuje usługi nazewnictwa, dla których urządzenie jest skonfigurowane. Może to wymagać wywołania perllub python, które są dość powszechne na większości platform uniksowych

np. to zwróci powłokę dla bieżącego użytkownika:

perl -e '@x=getpwuid($<); print $x[8]'
Stephen Harris
źródło
2

Możesz pobrać domyślną powłokę użytkownika ze środowiska w następujący sposób:

echo $SHELL

Ale nie tak:

echo $0

Ten ostatni powie ci tylko, jakiej powłoki używa Twój skrypt. Więc chcesz pierwszą opcję powyżej.

Alkss
źródło
0

Krótkie i bezbolesne:

getent passwd <USER> | cut -d : -f 7
David Foerster
źródło
0

Może to:

   grep $USER </etc/passwd | cut -f 7 -d ":"
użytkownik226946
źródło
Nie poprawia to żadnej z wcześniej udzielonych odpowiedzi.
Kusalananda
To nie zadziała, jeśli wielu użytkowników ma wspólne prace; np jeśli USER=fredwtedy będzie to pasuje fred, frederick, alfred, alfredo...
Stephen Harris