Jak ustalić bieżącą powłokę, nad którą pracuję

632

Jak mogę ustalić bieżącą powłokę, nad którą pracuję?

Czy wynik samego pspolecenia byłby wystarczający?

Jak można to zrobić w różnych wersjach Uniksa?

josh
źródło
9
Testowanie określonych możliwości (np. Czy dokonuje !podstawienia?) Jest prawdopodobnie bardziej przenośne niż znajdowanie nazwy powłoki. Lokalny zwyczaj może wymagać, abyś uruchomił coś o nazwie, /bin/shktóra może być popiołem, myślnikiem, uderzeniem itp.
msw
1
@msw: Wydaje się, że to dobry komentarz, ale nie zastanawiam się „jak?”.
nobar
Wydaje się, że nie ma prostej odpowiedzi na to pytanie. Jeśli nie możemy zapytać o powłokę, być może lepszym rozwiązaniem jest zawsze określenie powłoki. Nie jestem pewien, czy jest to zawsze możliwe, ale może łatwiej to osiągnąć, niż ludzie się domyślają.
nobar
To może pomóc -> opensourceforgeeks.blogspot.in/2013/05/…
Aniket Thakur
@Aniket, nie tyle pomocy, ile mogłoby się wydawać - to dotyczy tylko interaktywnych procesów powłoki.
Toby Speight

Odpowiedzi:

793
  • Istnieją trzy podejścia do znalezienia nazwy pliku wykonywalnego bieżącej powłoki:

    Zauważ, że wszystkie trzy podejścia można oszukać, jeśli plik wykonywalny powłoki jest /bin/sh, ale tak naprawdę bashna przykład zmienia się jego nazwę (co często się zdarza).

    Zatem na twoje drugie pytanie, czy pswynik da wynik, odpowiada „ nie zawsze ”.

    1. echo $0 - wypisze nazwę programu ... która w przypadku powłoki jest rzeczywistą powłoką.

    2. ps -ef | grep $$ | grep -v grep- wyszuka bieżący identyfikator procesu na liście uruchomionych procesów. Ponieważ bieżącym procesem jest powłoka, zostanie on uwzględniony.

      Nie jest to w 100% niezawodne, ponieważ możesz mieć inne procesy, których pslista zawiera taki sam numer jak identyfikator procesu powłoki, szczególnie jeśli ten identyfikator jest małą liczbą (na przykład, jeśli PID powłoki to „5”, możesz znaleźć procesy o nazwie „java5” lub „perl5” na tym samym grepwyjściu!). Jest to drugi problem związany z podejściem „ps”, poza tym, że nie można polegać na nazwie powłoki.

    3. echo $SHELL- Ścieżka do bieżącej powłoki jest przechowywana jako SHELLzmienna dla dowolnej powłoki. Zastrzeżeniem tego jest to, że jeśli uruchomisz powłokę jawnie jako podproces (na przykład nie jest to twoja powłoka logowania), zamiast tego otrzymasz wartość powłoki logowania. Jeśli jest to możliwe, użyj metody pslub $0.


  • Jeśli jednak plik wykonywalny nie pasuje do twojej aktualnej powłoki (np. /bin/shJest to właściwie bash lub ksh), potrzebujesz heurystyki. Oto niektóre zmienne środowiskowe specyficzne dla różnych powłok:

    • $version jest ustawiony na tcsh

    • $BASH jest ustawiony na bash

    • $shell (małe litery) ustawiono na rzeczywistą nazwę powłoki w csh lub tcsh

    • $ZSH_NAME jest ustawiony na zsh

    • ksh ma $PS3i $PS4ustawia, podczas gdy normalna powłoka Bourne'a ( sh) ma $PS1i $PS2ustawia. To wydaje się jak zwykle najtrudniejsze do odróżnienia - z jedyną różnicę w całym zbiorze zmiennych środowiskowych pomiędzy shi kshmamy zainstalowany na Solaris Boxen jest $ERRNO, $FCEDIT, $LINENO, $PPID, $PS3, $PS4, $RANDOM, $SECONDS, i $TMOUT.

DVK
źródło
$ {. sh.version} jest ustawiony na ksh93
fpmurphy
14
ps -p $$jak zauważa Matthew Slattery . Dla ksh: echo $KSH_VERSIONlub echo ${.sh.version}.
Wstrzymano do odwołania.
@Dennish - mój ksh w tej chwili nie ma ustawionego KSH_VERSION. i echo ${.sh.version}zwraca „Złe zastąpienie”. Zobacz moje rozwiązanie powyżej
DVK
3
ps -ef | grep …... To nie jest w 100% wiarygodne jako ...” Za pomocą prostego wyrażenia regularnego poprzez egreplub grep -emoże łatwo doprowadzić do wiarygodności dla-all-zamiarów-and-celów w 100%: ps -ef | egrep "^\s*\d+\s+$$\s+". W ^pilnuje, zaczynamy od początku linii, \d+zjada UID, urządzenie $$pasuje PID, a \s*i \s+konto dla & zapewnić odstępy między innymi częściami.
Slipp D. Thompson,
2
@ SlippD.Thompson nie działał w systemie GNU / Linux. Ale to wydaje się działać:ps -ef | awk '$2==pid' pid=$$
jarno
98

ps -p $$

powinien działać wszędzie tam, gdzie występują rozwiązania ps -ef i grepzrobić (na dowolnym wariancie Unix, który obsługuje opcje dla POSIXps ) i nie będzie cierpieć z powodu fałszywych alarmów wprowadzonych grepping na sekwencję cyfr, które mogą pojawić się w innym miejscu.

Matthew Slattery
źródło
12
Niektóre powłoki mają swoje wbudowane wersje, psktórych może nie zrozumieć, -pwięc może być konieczne użycie /bin/ps -p $$.
Wstrzymano do odwołania.
12
Wszystkie muszle, które znam, rozumieją, z $$wyjątkiem fishktórych będziesz musiał użyć ps -p %self.
Wstrzymano do odwołania.
3
W rzeczywistości nie powinieneś polegać na trudnych ścieżkach, takich jak /bin/ps. psmożna łatwo zainstalować (obecnie jest to całkiem normalne) /usr/bin. $(which ps) -p $$to lepszy sposób. Oczywiście nie zadziała to u ryb i prawdopodobnie innych skorup. Myślę, że jest (which ps) -p %selfw rybach.
Aron Cederholm
1
W niektórych minimalnych systemach, takich jak cienki pojemnik dokujący Debiana, ps może nie być tam. W takim przypadku takie podejście nadal działa:readlink /proc/$$/exe
mxmlnkn
jeśli twój shjest naśladowany bash, ps -p daje ci /usr/bin/bashnawet uruchomić go jakosh
Ding-Yi Chen
45

Próbować

ps -p $$ -oargs=

lub

ps -p $$ -ocomm=
Nahuel Fouilleul
źródło
4
To jest ładne krótkie. Korzystałem z siebie ps -o fname --no-headers $$.
Anne van Rossum
Dzięki. Uważam, że jest to najlepsza opcja do użycia w skrypcie do ochrony określonych poleceń bash test `ps -p $$ -ocomm=` == "bash" && do_something_that_only_works_in_bash. (Następny wiersz w moim skrypcie ma odpowiednik csh.)
craq
1
Odkryłem, że jeśli zrobisz to z podpowłoki, może to prowadzić do fałszywych dodatkowych linii poprzez dopasowanie PID rodzica, a także faktycznego procesu powłoki. W tym celu używam -qzamiast -p:SHELL=$(ps -ocomm= -q $$)
Steve
35

Jeśli chcesz tylko upewnić się, że użytkownik wywołuje skrypt za pomocą Bash:

if [ ! -n "$BASH" ] ;then echo Please run this script $0 with bash; exit 1; fi
Peter Lamberg
źródło
1
To powinien być ten bliżej szczytu. Wielkie dzięki.
Alex Skrypnyk
4
Nie powinno być bliżej góry, ponieważ w ogóle nie odpowiada na pytanie. Jeśli pytanie brzmiałoby „Jak sprawdzić, czy skrypt działa pod bash”, głosuję na to.
David Ferenczy Rogožan
2
@DawidFerenczy - To pytanie jest jednak najlepszym wynikiem podczas wyszukiwania tego wyrażenia. Na dłuższą metę myślę, że o wiele ważniejsze jest, aby odpowiedzi odpowiadały na to, czego ludzie szukają, niż odpowiadały pierwotnemu pytaniu.
ArtOfWarfare
3
Ponadto zmienna $ BASH jest zdefiniowana w tcsh, jeśli tcsh jest wywoływany z bash
18446744073709551615
To bardzo przydatne, dziękuję. Wystarczy dostosować go trochę, stawiając to jako drugiej linii po #!/bin/bash: if [ ! -n "$BASH" ] ;then exec bash $0; fi. W tym wierszu skrypt jest uruchamiany przy użyciu bash, nawet jeśli zaczął używać ksh lub sh. Mój przypadek użycia nie wymaga argumentów z wiersza poleceń, ale można je dodać po nim, $0jeśli to konieczne.
joanis
20

Możesz spróbować:

ps | grep `echo $$` | awk '{ print $4 }'

Lub:

echo $SHELL
karlphillip
źródło
6
Jaki jest sens grep, po którym następuje awk, kiedy /pattern/ { action }to zrobi?
Jens
# in zshell alias shell = 'echo $ {SHELL: t}'
SergioAraujo
4
$SHELLzmienna środowiskowa zawiera powłokę, która jest domyślnie skonfigurowana dla bieżącego użytkownika. Nie odzwierciedla powłoki, która jest obecnie uruchomiona. Lepiej jest także używać ps -p $$niż grepping $$ z powodu fałszywych wyników pozytywnych.
David Ferenczy Rogožan
Środowisko $ SHELL zmienna wskazuje na powłokę „macierzystą”, jak określono w specyfikacji POSIX: SHELL Ta zmienna reprezentuje nazwę ścieżki preferowanego przez użytkownika interpretera języka poleceń. Dlatego wartość $ SHELL może nie być bieżącą powłoką.
Theo
wszystko wewnątrz awk,ps | awk '$1=='$$' { n=split($4,a,"/"); print a[n] }'
go2null
16

$SHELLnie zawsze musi pokazywać bieżącą powłokę. Odzwierciedla tylko domyślną powłokę, którą należy wywołać.

Aby przetestować powyższe, powiedzmy, że bashjest domyślną powłoką, spróbuj echo $SHELL, a następnie w tym samym terminalu, przejdź do innej powłoki ( na przykład KornShell (ksh)) i spróbuj $SHELL. W obu przypadkach zobaczysz wynik jako bash.

Aby uzyskać nazwę bieżącej powłoki, użyj cat /proc/$$/cmdline. I ścieżka do powłoki wykonywalnej przez readlink /proc/$$/exe.

sr01853
źródło
8
... pod warunkiem, że masz /proc.
tripleee
10

ps jest najbardziej niezawodną metodą. Nie można zagwarantować, że zmienna środowiskowa SHELL zostanie ustawiona, a nawet jeśli tak, można ją łatwo sfałszować.

ennuikiller
źródło
12
+1 $ SHELL jest domyślną powłoką dla programów, które muszą ją odrodzić. To niekoniecznie odzwierciedla aktualnie działającą powłokę.
Jim Lewis,
8

Mam prostą sztuczkę, aby znaleźć bieżącą powłokę. Wystarczy wpisać losowy ciąg znaków (który nie jest poleceniem). Nie powiedzie się i zwróci błąd „nie znaleziono”, ale na początku linii powie, która to powłoka:

ksh: aaaaa: not found [No such file or directory]
bash: aaaaa: command not found
użytkownik5659949
źródło
3
Nic dobrego w skrypcie. echo 'aaaa' > script; chmod +x script; ./scriptdaje./script.sh: 1: aaaa: not found
szczupły
6

Poniższe zawsze podaje rzeczywistą używaną powłokę - pobiera nazwę rzeczywistego pliku wykonywalnego, a nie nazwę powłoki (tj. ksh93Zamiast kshitp.). Bo /bin/shpokaże rzeczywistą używaną powłokę, tj dash.

ls -l /proc/$$/exe | sed 's%.*/%%'

Wiem, że jest wielu, którzy mówią ls wyjściowe nigdy nie powinny być przetwarzane, ale jakie jest prawdopodobieństwo, że będziesz mieć używaną powłokę nazwaną znakami specjalnymi lub umieszczoną w katalogu o nazwach specjalnych? Jeśli nadal tak jest, istnieje wiele innych przykładów robienia tego inaczej.

Jak zauważył Toby Speight , byłby to bardziej właściwy i czystszy sposób osiągnięcia tego samego:

basename $(readlink /proc/$$/exe)
Vadimbog
źródło
3
To tylko błędy we wszystkich Unices, które nie zapewniają /proc. Nie cały świat jest systemem Linux.
Jens
5
A jeśli jesteś na Linuksie, wolimy basename $(readlink /proc/$$/exe)do ls+ sed+ echo.
Toby Speight
1
To da nazwę rzeczywistego pliku wykonywalnego , a nie rzeczywistej powłoki . Gdy rzeczywista powłoka jest połączona jako aplet zajęty, powiedzmy ash -> /bin/busybox, to da / bin / busybox.
stepse
6

Próbowałem wielu różnych podejść i najlepsze dla mnie jest:

ps -p $$

Działa również pod Cygwinem i nie może generować fałszywych alarmów jako grepping PID. Po pewnym czyszczeniu wyświetla tylko nazwę pliku wykonywalnego (pod Cygwin ze ścieżką):

ps -p $$ | tail -1 | awk '{print $NF}'

Możesz stworzyć funkcję, żebyś nie musiał jej zapamiętywać:

# Print currently active shell
shell () {
  ps -p $$ | tail -1 | awk '{print $NF}'
}

... a następnie po prostu wykonaj shell.

Został przetestowany pod Debianem i Cygwinem.

David Ferenczy Rogožan
źródło
W mojej konfiguracji (Cygwin | Windows 7) Twoja odpowiedź jest najlepsza, a ps -p $$ | ogon -1 | gawk „{print $ NF}” działa nawet z cmd bez $ bash. Uwaga gawk zamiast awk, ponieważ awk działa tylko z bash.
WebComer
@WebComer Przepraszamy, nie jestem pewien, co masz na myśli przez „ działa nawet z cmd bez $ bash ”. Nawet jeśli masz porty systemu Windows ps, taila gawkcmd nie definiuje się $$jako PID, więc zdecydowanie nie może działać pod zwykłym cmd.
David Ferenczy Rogožan
Dlaczego nie po prostu ps -p$$ -o comm=? POSIX mówi, że określenie wszystkich nagłówków pustych całkowicie pomija nagłówek. Nadal nie udaje nam się (podobnie jak wszystkie psodpowiedzi), gdy pozyskujemy bezpośrednio wykonany skrypt (np #!/bin/sh.).
Toby Speight
5

Mój wariant drukowania procesu nadrzędnego:

ps -p $$ | awk '$1 == PP {print $4}' PP=$$

Nie uruchamiaj niepotrzebnych aplikacji, gdy AWK może to zrobić za Ciebie.

Matthew Stier
źródło
2
Po co uruchamiać niepotrzebne awk, kiedy ps -p "$$" -o 'comm='można to dla Ciebie zrobić?
Toby Speight
5

Istnieje wiele sposobów na znalezienie powłoki i odpowiadającej jej wersji. Oto kilka, które działały dla mnie.

Bezpośredni

  1. $> echo $ 0 (Podaje nazwę programu. W moim przypadku wynikiem było -bash .)
  2. $> $ SHELL (To zabierze Cię do powłoki, aw linii pojawi się nazwa i wersja powłoki. W moim przypadku bash3.2 $ .)
  3. $> echo $ SHELL (To da ci ścieżkę do pliku wykonywalnego. W moim przypadku / bin / bash .)
  4. $> $ SHELL --version (Daje to pełne informacje o oprogramowaniu powłoki z typem licencji)

Podstępne podejście

$> ******* (Wpisz zestaw losowych znaków, a na wyjściu otrzymasz nazwę powłoki. W moim przypadku -bash: rozdział2-a-sample-isomorphic-app: polecenie nie znaleziono )

Devang Paliwal
źródło
3

Pod warunkiem, że /bin/shobsługujesz standard POSIX, a system ma lsofzainstalowaną komendę - lsofw tym przypadku może być alternatywą pid2path- możesz także użyć (lub dostosować) następującego skryptu, który wypisuje pełne ścieżki:

#!/bin/sh
# cat /usr/local/bin/cursh
set -eu
pid="$$"

set -- sh bash zsh ksh ash dash csh tcsh pdksh mksh fish psh rc scsh bournesh wish Wish login

unset echo env sed ps lsof awk getconf

# getconf _POSIX_VERSION  # reliable test for availability of POSIX system?
PATH="`PATH=/usr/bin:/bin:/usr/sbin:/sbin getconf PATH`"
[ $? -ne 0 ] && { echo "'getconf PATH' failed"; exit 1; }
export PATH

cmd="lsof"
env -i PATH="${PATH}" type "$cmd" 1>/dev/null 2>&1 || { echo "$cmd not found"; exit 1; }

awkstr="`echo "$@" | sed 's/\([^ ]\{1,\}\)/|\/\1/g; s/ /$/g' | sed 's/^|//; s/$/$/'`"

ppid="`env -i PATH="${PATH}" ps -p $pid -o ppid=`"
[ "${ppid}"X = ""X ] && { echo "no ppid found"; exit 1; }

lsofstr="`lsof -p $ppid`" || 
   { printf "%s\n" "lsof failed" "try: sudo lsof -p \`ps -p \$\$ -o ppid=\`"; exit 1; }

printf "%s\n" "${lsofstr}" | 
   LC_ALL=C awk -v var="${awkstr}" '$NF ~ var {print $NF}'
Carlo
źródło
1
to działa na ryby! ale dla mnie nie powiedzie się bash, z powodu opcji -i(-> ignore environment) envw linii, w której sprawdzasz lsofdostępność. kończy się niepowodzeniem: env -i PATH="${PATH}" type lsof->env: ‘type’: No such file or directory
hoijui
2

Jeśli chcesz tylko sprawdzić, czy korzystasz (konkretna wersja) Bash, najlepszym sposobem na to jest użycie $BASH_VERSINFOzmiennej tablicowej. Jako zmienna tablicowa (tylko do odczytu) nie można jej ustawić w środowisku, więc możesz być pewien, że pochodzi ona (jeśli w ogóle) z bieżącej powłoki.

Ponieważ jednak Bash ma inne zachowanie po wywołaniu jako sh, musisz również sprawdzić, czy $BASHzmienna środowiskowa kończy się na /bash.

W skrypcie, który napisałem, który używa nazw funkcji z -(bez podkreślenia) i zależy od tablic asocjacyjnych (dodanych w Bash 4), mam następującą kontrolę poprawności (z pomocnym komunikatem o błędzie użytkownika):

case `eval 'echo $BASH@${BASH_VERSINFO[0]}' 2>/dev/null` in
    */bash@[456789])
        # Claims bash version 4+, check for func-names and associative arrays
        if ! eval "declare -A _ARRAY && func-name() { :; }" 2>/dev/null; then
            echo >&2 "bash $BASH_VERSION is not supported (not really bash?)"
            exit 1
        fi
        ;;
    */bash@[123])
        echo >&2 "bash $BASH_VERSION is not supported (version 4+ required)"
        exit 1
        ;;
    *)
        echo >&2 "This script requires BASH (version 4+) - not regular sh"
        echo >&2 "Re-run as \"bash $CMD\" for proper operation"
        exit 1
        ;;
esac

W pierwszym przypadku można pominąć nieco paranoiczne sprawdzenie działania funkcji i założyć, że przyszłe wersje Bash będą kompatybilne.

Alex Dupuy
źródło
2

Żadna z odpowiedzi nie działała z fishpowłoką (nie ma zmiennych $$lub $0).

Działa to dla mnie (testowane na sh, bash, fish, ksh, csh, true, tcsh, i zsh; openSUSE 13.2):

ps | tail -n 4 | sed -E '2,$d;s/.* (.*)/\1/'

To polecenie wyświetla ciąg podobny do bash. Tutaj jestem tylko przy użyciu ps, tailoraz sed(bez extesions GNU, spróbuj dodać --posixto sprawdzić). Wszystkie są standardowymi poleceniami POSIX. Jestem pewien, że tailmożna go usunąć, ale moje sedfu nie jest wystarczająco silne, aby to zrobić.

Wydaje mi się, że to rozwiązanie nie jest zbyt przenośne, ponieważ nie działa w systemie OS X. :(

rominf
źródło
Dostaję sed: invalid option -- 'E'bash 3.2.51 i tcsh 6.15.00
craq
2

Moje rozwiązanie:

ps -o command | grep -v -e "\<ps\>" -e grep -e tail | tail -1

Powinno to być przenośne na różnych platformach i powłokach. Wykorzystuje psjak inne rozwiązania, ale to nie zależy sedczy awki odfiltrowuje śmieci z orurowaniem i pssobie tak, że powłoka powinna być zawsze ostatni wpis. W ten sposób nie musimy polegać na nieprzenośnych zmiennych PID ani wybierać odpowiednich linii i kolumn.

Testowałem na Debianie i macOS z powłoką Bash, Z (zsh ) i fish (który nie działa z większością tych rozwiązań bez zmiany wyrażenia specjalnie dla ryb, ponieważ używa innej zmiennej PID).

wickles
źródło
1
echo $$ # Gives the Parent Process ID 
ps -ef | grep $$ | awk '{print $8}' # Use the PID to see what the process is.

Od Skąd wiesz, jaka jest twoja obecna powłoka? .

Moisei
źródło
3
To nie jest proces nadrzędny - to proces bieżący.
Wstrzymano do odwołania.
7
Używanie grep $$jest zawodne. ps -ef | awk -v pid=$$ '$2==pid { print $8 }'jest lepszy, ale dlaczego nie po prostu użyć ps -p $$?
musiphil
1

W systemie Mac OS X (i FreeBSD):

ps -p $$ -axco command | sed -n '$p' 
zaga
źródło
2
Próbowałem tego podczas korzystania zshi dało mi to -bash.
user137369
W moim systemie (teraz), przetestowanym za pomocą bash i dash, ten powrót mutt...: -b
F. Hauri
1

Grepping PID z wyjścia „ps” nie jest potrzebny, ponieważ można odczytać odpowiedni wiersz polecenia dla dowolnego PID ze struktury katalogów / proc:

echo $(cat /proc/$$/cmdline)

Jednak nie może to być nic lepszego niż po prostu:

echo $0

Aby uruchomić właściwie inną powłokę niż wskazuje nazwa, jednym z pomysłów jest zażądanie wersji z powłoki przy użyciu wcześniej otrzymanej nazwy:

<some_shell> --version

sh wydaje się nie działać z kodem wyjścia 2, podczas gdy inni dają coś pożytecznego (ale nie jestem w stanie zweryfikować wszystkiego, ponieważ ich nie mam):

$ sh --version
sh: 0: Illegal option --
echo $?
2
ajaaskel
źródło
1

To nie jest bardzo czyste rozwiązanie, ale robi to, co chcesz.

# MUST BE SOURCED..
getshell() {
    local shell="`ps -p $$ | tail -1 | awk '{print $4}'`"

    shells_array=(
    # It is important that the shells are listed in descending order of their name length.
        pdksh
        bash dash mksh
        zsh ksh
        sh
    )

    local suited=false
    for i in ${shells_array[*]}; do
        if ! [ -z `printf $shell | grep $i` ] && ! $suited; then
            shell=$i
            suited=true
        fi
    done

    echo $shell
}
getshell

Teraz możesz użyć $(getshell) --version .

Działa to jednak tylko w przypadku powłok podobnych do KornShell (ksh).

theoden8
źródło
1
„Działa to jednak tylko w przypadku powłok podobnych do ksh”. Czy mówisz, że muszę zweryfikować powłokę przed uruchomieniem tego? Hmm ...
jpaugh,
@jpaugh wykazy muszą być obsługiwane przez powłokę sourcing ten kod, który nie jest w przypadku dash, yashetc. Zwykle, jeśli używasz bash, zsh, ksh, cokolwiek - nie należy dbać o takich rzeczach.
theoden8
Więc liczysz bash jako „ksh-like”? Rozumiem. To ma więcej sensu
jpaugh
@ jpaugh, cóż, to miałem na myśli, ponieważ kshzestaw funkcji jest w większości podzbiorem bashfunkcji (chociaż nie sprawdziłem tego dokładnie).
theoden8
1

Wykonaj następujące czynności, aby wiedzieć, czy twoja powłoka używa Dash / Bash.

ls –la /bin/sh:

  • jeśli wynikiem jest /bin/sh -> /bin/bash==> Twoja powłoka używa Bash.

  • jeśli wynikiem jest /bin/sh ->/bin/dash==> Twoja powłoka używa Dash.

Jeśli chcesz zmienić Bash na Dash lub odwrotnie, użyj poniższego kodu:

ln -s /bin/bash /bin/sh (zmień powłokę na Bash)

Uwaga : Jeśli powyższe polecenie powoduje błąd: / bin / sh już istnieje, usuń / bin / sh i spróbuj ponownie.

siedmiodniowa żałoba
źródło
0

I wymyśliłem to

sed 's/.*SHELL=//; s/[[:upper:]].*//' /proc/$$/environ
Ivan
źródło
Działa to tylko w systemie Linux ! Nie MacOS ani BSD !!
F. Hauri
-1

Prosimy użyć następującego polecenia:

ps -p $$ | tail -1 | awk '{print $4}'
Ranjithkumar T.
źródło
Pierwszy to nonsens, echo $SHELLrobi to, co próbujesz zrobić i robi to dobrze. Drugi też nie jest dobry, ponieważ $SHELLzmienna środowiskowa zawiera domyślną powłokę dla bieżącego użytkownika, a nie aktualnie działającą powłokę. Jeśli mam na przykład bashUstaw jako domyślny shell, wykonanie zshi echo $SHELLbędziesz drukować bash.
David Ferenczy Rogožan
Masz rację Dawid Ferenczy, możemy użyć polecenia ps, aby określić bieżącą powłokę. [# ps -p $$ | ogon -1 | awk „{print $ 4}”].
Ranjithkumar T
echo $SHELLmogą być śmieci: ~ $ echo $SHELL /bin/zsh ~ $ bash bash-4.3$ echo $SHELL /bin/zsh bash-4.3$
SaltwaterC
-2

Ten działa dobrze na Red Hat Linux (RHEL), macOS, BSD i niektórych systemach AIX :

ps -T $$ | awk 'NR==2{print $NF}' 

alternatywnie, poniższy powinien również działać, jeśli pstree jest dostępny,

pstree | egrep $$ | awk 'NR==2{print $NF}'
Martin Zahrubsky
źródło