Cách xác định shell hiện tại tôi đang làm việc


634

Làm thế nào tôi có thể xác định shell hiện tại tôi đang làm việc?

Chỉ đầu ra của pslệnh sẽ là đủ?

Làm thế nào điều này có thể được thực hiện trong các hương vị khác nhau của Unix?


9
Kiểm tra các khả năng cụ thể (ví dụ: nó có !thay thế không?) Có thể dễ mang theo hơn là tìm tên của vỏ. Phong tục địa phương có thể khiến bạn chạy một cái gì đó có tên /bin/shthực sự có thể là tro, gạch ngang, bash, v.v.
msw

1
@msw: Có vẻ như là một bình luận tốt ngoại trừ nó khiến tôi tự hỏi "làm thế nào?".
tộc

Dường như không có câu trả lời đơn giản cho câu hỏi này. Nếu chúng ta không thể truy vấn shell, có thể cách tiếp cận tốt hơn là luôn chỉ định shell. Tôi không chắc chắn rằng điều này luôn luôn có thể, nhưng có lẽ nó dễ thực hiện hơn mọi người thường nghĩ.
tộc


@Aniket, không giúp ích nhiều như bạn nghĩ - điều đó chỉ quan tâm đến các quy trình vỏ tương tác .
Toby Speight

Câu trả lời:


794
  • Có ba cách tiếp cận để tìm tên của shell hiện tại:

    Xin lưu ý rằng cả ba cách tiếp cận đều có thể bị đánh lừa nếu khả năng thực thi của shell là /bin/sh, nhưng nó thực sự được đổi tên bash, chẳng hạn (thường xảy ra).

    Do đó, câu hỏi thứ hai của bạn về việc liệu psđầu ra sẽ làm được trả lời với " không phải luôn luôn ".

    1. echo $0 - sẽ in tên chương trình ... mà trong trường hợp shell là shell thực tế.

    2. ps -ef | grep $$ | grep -v grep- cái này sẽ tìm ID tiến trình hiện tại trong danh sách các tiến trình đang chạy. Vì quy trình hiện tại là vỏ, nó sẽ được bao gồm.

      Điều này không đáng tin cậy 100%, vì bạn có thể có các quy trình khácpsdanh sách bao gồm cùng số với ID quy trình của shell, đặc biệt nếu ID đó là một số nhỏ (ví dụ: nếu PID của shell là "5", bạn có thể tìm thấy các quy trình được gọi "Java5" hoặc "perl5" trong cùng một grepđầu ra!). Đây là vấn đề thứ hai với cách tiếp cận "ps", trên hết là không thể dựa vào tên shell.

    3. echo $SHELL- Đường dẫn đến shell hiện tại được lưu trữ dưới dạng SHELLbiến cho bất kỳ shell nào. Thông báo trước cho điều này là nếu bạn khởi chạy một lớp vỏ rõ ràng dưới dạng một quy trình con (ví dụ: đó không phải là vỏ đăng nhập của bạn), bạn sẽ nhận được giá trị của vỏ đăng nhập thay thế. Nếu đó là một khả năng, sử dụng pshoặc $0cách tiếp cận.


  • Tuy nhiên, nếu thực thi không khớp với vỏ thực tế của bạn (ví dụ như /bin/shthực sự là bash hoặc ksh), bạn cần heuristic. Dưới đây là một số biến môi trường cụ thể cho các loại vỏ khác nhau:

    • $version được đặt trên tcsh

    • $BASH được đặt trên bash

    • $shell (chữ thường) được đặt thành tên shell thực tế trong csh hoặc tcsh

    • $ZSH_NAME được đặt trên zsh

    • ksh có $PS3$PS4thiết lập, trong khi shell Bourne bình thường ( sh) chỉ có $PS1$PS2thiết lập. Điều này thường có vẻ như khó khăn nhất để phân biệt - các chỉ chênh lệch trong toàn bộ tập hợp các biến môi trường giữa shkshchúng tôi đã cài đặt trên Solaris boxen là $ERRNO, $FCEDIT, $LINENO, $PPID, $PS3, $PS4,$RANDOM , $SECONDS, và $TMOUT.


$ {. sh.version} được đặt trên ksh93
fpmurphy

14
ps -p $$như Matthew Slattery chỉ ra. Dành cho ksh: echo $KSH_VERSIONhoặc echo ${.sh.version}.
Tạm dừng cho đến khi có thông báo mới.

@Dennish - ksh của tôi ngay bây giờ không có bộ KSH_VERSION. và echo ${.sh.version}trả về "Thay thế xấu". Xem giải pháp của tôi ở trên
DVK

3
ps -ef | grep …... Đây không phải là 100% đáng tin cậy như ...” Sử dụng một biểu thức chính quy đơn giản thông qua egrephoặc grep -ecó thể dễ dàng mang lại độ tin cậy lên đến cho tất cả-intents-and-mục đích 100%: ps -ef | egrep "^\s*\d+\s+$$\s+". Các ^làm cho chắc chắn chúng tôi đang bắt đầu từ đầu dòng, các \d+ngốn lên UID thì $$phù hợp với PID, và \s*\s+tài khoản cho & đảm bảo khoảng trắng giữa các bộ phận khác.
Slipp D. Thompson

2
@ SlippD.Thndry không hoạt động trong GNU / Linux. Nhưng điều này dường như hoạt động:ps -ef | awk '$2==pid' pid=$$
jarno

98

ps -p $$

nên hoạt động ở bất cứ nơi nào mà các giải pháp liên quan ps -efgrepthực hiện (trên bất kỳ biến thể Unix nào hỗ trợ các tùy chọn POSIX chops ) và sẽ không phải chịu các lỗi tích cực được đưa ra bằng cách grepping cho một chuỗi các chữ số có thể xuất hiện ở nơi khác.


12
Một số shell có phiên bản dựng sẵn riêng pscó thể không hiểu -pnên bạn có thể cần sử dụng /bin/ps -p $$.
Tạm dừng cho đến khi có thông báo mới.

13
Tất cả các shell tôi quen thuộc đều hiểu $$ngoại trừ việc fishbạn sẽ phải sử dụng ps -p %self.
Tạm dừng cho đến khi có thông báo mới.

3
Trên thực tế, bạn không nên dựa vào một con đường khó như /bin/ps. pscó thể dễ dàng (thực sự là nó khá bình thường ngày nay) được cài đặt trong /usr/bin. $(which ps) -p $$là một cách tốt hơn. Tất nhiên, điều này sẽ không hoạt động trong cá, và có thể một số vỏ khác. Tôi nghĩ rằng nó là (which ps) -p %selftrong cá.
Aron Cederholm

1
Trong một số hệ thống tối thiểu như thùng chứa docker-slim, ps có thể không ở đó. Trong trường hợp đó, cách tiếp cận này vẫn hoạt động:readlink /proc/$$/exe
mxmlnkn

nếu bạn shđược mô phỏng theo bash, ps -p cung cấp cho bạn /usr/bin/bashngay cả khi bạn chạy nó nhưsh
Đinh-Yi Chen

45

Thử

ps -p $$ -oargs=

hoặc là

ps -p $$ -ocomm=

4
Đây là một ngắn tốt đẹp. Tôi đã sử dụng bản thân mình ps -o fname --no-headers $$.
Anne van Rossum

Cảm ơn. Tôi thấy đây là tùy chọn tốt nhất để sử dụng trong tập lệnh để bảo vệ các lệnh cụ thể bash test `ps -p $$ -ocomm=` == "bash" && do_something_that_only_works_in_bash. (Dòng tiếp theo trong tập lệnh của tôi có tương đương với csh.)
craq

1
Tôi đã thấy rằng nếu bạn thực hiện điều này từ bên trong một lớp con thì nó có thể dẫn đến các dòng bổ sung giả bằng cách khớp với PID của cha mẹ cũng như quá trình shell thực tế. Đối với điều này, tôi sử dụng -qthay vì -p:SHELL=$(ps -ocomm= -q $$)
Steve

35

Nếu bạn chỉ muốn đảm bảo người dùng đang gọi một tập lệnh với Bash:

if [ ! -n "$BASH" ] ;then echo Please run this script $0 with bash; exit 1; fi

1
Đây phải là một trong những gần hơn với đầu. Cảm ơn rất nhiều.
Alex Skrypnyk

4
Nó không nên ở gần đầu, bởi vì nó không trả lời câu hỏi nào cả. Nếu câu hỏi sẽ là "Cách kiểm tra xem tập lệnh có chạy dưới bash không", tôi bỏ phiếu cho nó.
David Ferenczy Rogožan

2
@DawidFerenczy - Câu hỏi này là kết quả hàng đầu khi bạn tìm kiếm cụm từ đó. Về lâu dài, tôi nghĩ điều quan trọng hơn nhiều là câu trả lời trả lời những gì mọi người đang tìm kiếm hơn là trả lời câu hỏi ban đầu là gì.
ArtOfWarfare

3
Ngoài ra, biến $ BASH được xác định theo tcsh nếu tcsh được gọi từ bash
18446744073709551615

Điều này rất hữu ích, cảm ơn bạn. Chỉ cần điều chỉnh nó một chút, đặt đây là dòng thứ hai sau #!/bin/bash: if [ ! -n "$BASH" ] ;then exec bash $0; fi. Với dòng này, tập lệnh được chạy bằng bash ngay cả khi bắt đầu sử dụng ksh hoặc sh. Ca sử dụng của tôi không cần đối số dòng lệnh, nhưng chúng có thể được thêm vào sau $0nếu cần.
joanis

20

Bạn co thể thử:

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

Hoặc là:

echo $SHELL

6
Điểm của grep theo sau bởi awk, khi nào /pattern/ { action }sẽ làm gì?
Jens

# in zshell alias shell = 'echo $ {SHELL: t}'
SergioAraujo

4
$SHELLbiến môi trường chứa shell, được cấu hình làm mặc định cho người dùng hiện tại. Nó không phản ánh một vỏ, hiện đang chạy. Ngoài ra, nó tốt hơn để sử dụng ps -p $$hơn grepping $$ vì dương tính giả.
David Ferenczy Rogožan

Các env $ SHELL. biến chỉ đến trình bao 'cha mẹ', như được chỉ định trong thông số POSIX: SHELL Biến này sẽ đại diện cho một tên đường dẫn của trình thông dịch ngôn ngữ lệnh ưa thích của người dùng. Do đó, giá trị của $ SHELL có thể không phải là vỏ hiện tại.
Theo

tất cả trong awk,ps | awk '$1=='$$' { n=split($4,a,"/"); print a[n] }'
go2null

16

$SHELLkhông cần phải luôn luôn hiển thị vỏ hiện tại. Nó chỉ phản ánh shell mặc định được gọi.

Để kiểm tra ở trên, giả sử bashlà shell mặc định, hãy thử echo $SHELL, và sau đó trong cùng một thiết bị đầu cuối, hãy vào một số shell khác ( ví dụ KornShell (ksh)) và thử$SHELL . Bạn sẽ thấy kết quả là bash trong cả hai trường hợp.

Để có được tên của shell hiện tại, sử dụng cat /proc/$$/cmdline. Và đường dẫn đến shell thực thi bởi readlink /proc/$$/exe.


8
... Miễn là bạn có /proc.
tripleee

10

ps là phương pháp đáng tin cậy nhất. Biến môi trường SHELL không được đảm bảo được đặt và ngay cả khi có, nó có thể dễ dàng bị giả mạo.


12
+1 $ SHELL là hệ vỏ mặc định cho các chương trình cần sinh ra một. Nó không nhất thiết phản ánh lớp vỏ hiện đang chạy.
Jim Lewis

8

Tôi có một mẹo đơn giản để tìm vỏ hiện tại. Chỉ cần gõ một chuỗi ngẫu nhiên (không phải là một lệnh). Nó sẽ thất bại và trả về lỗi "không tìm thấy", nhưng ở đầu dòng, nó sẽ cho biết đó là shell nào:

ksh: aaaaa: not found [No such file or directory]
bash: aaaaa: command not found

3
Không tốt trong một kịch bản. echo 'aaaa' > script; chmod +x script; ./scriptcho./script.sh: 1: aaaa: not found
mỏng

6

Sau đây sẽ luôn cung cấp shell thực tế được sử dụng - nó lấy tên của thực tế thực tế chứ không phải tên shell (tức là ksh93thay vì ksh, v.v.). Đối với /bin/sh, nó sẽ hiển thị vỏ thực tế được sử dụng, tức là dash.

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

Tôi biết rằng có nhiều người nói rằng ls đầu ra không bao giờ được xử lý, nhưng xác suất bạn sẽ có một vỏ bạn đang sử dụng được đặt tên bằng các ký tự đặc biệt hoặc được đặt trong một thư mục có tên các ký tự đặc biệt là gì? Nếu đây vẫn là trường hợp, có rất nhiều ví dụ khác về việc làm nó khác đi.

Như Toby Speight đã chỉ ra , đây sẽ là một cách đúng đắn và gọn gàng hơn để đạt được điều tương tự:

basename $(readlink /proc/$$/exe)

3
Đây chỉ là lỗi trên tất cả các Thông báo không cung cấp /proc. Không phải tất cả thế giới một hộp Linux.
Jens

5
Và nếu bạn đang trên Linux, chúng tôi muốn basename $(readlink /proc/$$/exe)để ls+ sed+ echo.
Toby Speight

1
Điều này sẽ cung cấp cho các tên của thực tế thực thi , không phải là thực tế vỏ . Khi shell thực tế được liên kết dưới dạng applet busybox, giả sử ash -> /bin/busybox, cái này sẽ cho / bin / busybox.
bước

6

Tôi đã thử nhiều cách tiếp cận khác nhau và cách tốt nhất đối với tôi là:

ps -p $$

Nó cũng hoạt động theo Cygwin và không thể tạo ra dương tính giả khi grepping PID. Với một số dọn dẹp, nó chỉ xuất ra một tên thực thi (dưới Cygwin với đường dẫn):

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

Bạn có thể tạo một chức năng để bạn không phải ghi nhớ nó:

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

... và sau đó chỉ cần thực thi shell.

Nó đã được thử nghiệm theo Debian và Cygwin.


Theo thiết lập của tôi (Cygwin | Windows 7), câu trả lời của bạn là câu trả lời hay nhất và ps -p $$ | đuôi -1 | gawk '{print $ NF}' hoạt động ngay cả từ cmd mà không có $ bash. Xin lưu ý gawk thay vì awk, vì awk chỉ hoạt động từ bash.
WebComer

@WebComer Xin lỗi, tôi không chắc ý của bạn là " hoạt động ngay cả từ cmd mà không có $ bash ". Ngay cả khi bạn có các cổng Windows ps, tailgawk, cmd không định nghĩa $$là PID nên nó chắc chắn không thể hoạt động dưới cmd đơn giản.
David Ferenczy Rogožan

Tại sao không đơn giản ps -p$$ -o comm=? POSIX nói rằng việc chỉ định tất cả các tiêu đề trống sẽ loại bỏ hoàn toàn tiêu đề. Chúng tôi vẫn thất bại (giống như tất cả các pscâu trả lời) khi chúng tôi có nguồn gốc từ một tập lệnh được thực thi trực tiếp (ví dụ #!/bin/sh).
Toby Speight

5

Biến thể của tôi về in quy trình cha mẹ:

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

Đừng chạy các ứng dụng không cần thiết khi AWK có thể làm điều đó cho bạn.


2
Tại sao chạy không cần thiết awk, khi nào ps -p "$$" -o 'comm='có thể làm điều đó cho bạn?
Toby Speight

5

Có nhiều cách để tìm ra vỏ và phiên bản tương ứng của nó. Dưới đây là một số ít làm việc cho tôi.

Nói thẳng

  1. $> echo $ 0 (Cung cấp cho bạn tên chương trình. Trong trường hợp của tôi, đầu ra là -bash .)
  2. $> $ SHELL (Điều này sẽ đưa bạn vào shell và trong lời nhắc bạn sẽ nhận được tên và phiên bản shell. Trong trường hợp của tôi bash3.2 $ .)
  3. $> echo $ SHELL (Điều này sẽ cung cấp cho bạn đường dẫn thực thi. Trong trường hợp của tôi / bin / bash .)
  4. $> $ SHELL --version (Điều này sẽ cung cấp thông tin đầy đủ về phần mềm shell với loại giấy phép)

Cách tiếp cận táo bạo

$> ******* (Nhập một tập hợp các ký tự ngẫu nhiên và trong đầu ra, bạn sẽ nhận được tên shell. Trong trường hợp của tôi -bash: chương2-a-sample-isomorphic-app: không tìm thấy lệnh )


3

Với điều kiện là bạn /bin/shhỗ trợ tiêu chuẩn POSIX và hệ thống của bạn đã lsofcài đặt lệnh - một giải pháp thay thế khả dĩ lsoftrong trường hợp này là pid2path- bạn cũng có thể sử dụng (hoặc điều chỉnh) tập lệnh sau in các đường dẫn đầy đủ:

#!/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}'

1
cái này hoạt động ở cá! nhưng đối với tôi, thất bại trong bash, vì -itùy chọn (-> bỏ qua môi trường) envtrong dòng nơi bạn kiểm tra lsofcó sẵn. nó thất bại với: env -i PATH="${PATH}" type lsof->env: ‘type’: No such file or directory
hoijui

2

Nếu bạn chỉ muốn kiểm tra xem bạn có đang chạy (một phiên bản cụ thể của) Bash hay không, cách tốt nhất để làm điều đó là sử dụng $BASH_VERSINFO biến mảng. Là một biến mảng (chỉ đọc), nó không thể được đặt trong môi trường, vì vậy bạn có thể chắc chắn rằng nó đang đến (nếu có) từ shell hiện tại.

Tuy nhiên, vì Bash có một hành vi khác khi được gọi là sh, bạn cũng cần kiểm tra $BASHbiến môi trường kết thúc bằng /bash.

Trong một kịch bản tôi đã viết sử dụng tên hàm với -(không phải dấu gạch dưới) và phụ thuộc vào mảng kết hợp (được thêm vào Bash 4), tôi có kiểm tra độ tỉnh táo sau (với thông báo lỗi người dùng hữu ích):

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

Bạn có thể bỏ qua kiểm tra chức năng hơi hoang tưởng cho các tính năng trong trường hợp đầu tiên và chỉ cần giả định rằng các phiên bản Bash trong tương lai sẽ tương thích.


2

Không có câu trả lời nào hoạt động với fishshell (nó không có các biến $$hoặc$0 ).

Này hoạt động đối với tôi (thử nghiệm trên sh, bash, fish, ksh, csh, true, tcsh, và zsh; openSUSE 13.2):

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

Lệnh này xuất ra một chuỗi như bash. Ở đây tôi chỉ sử dụng ps, tailsed(không có phần mở rộng GNU; hãy thử thêm --posixđể kiểm tra). Chúng đều là các lệnh POSIX tiêu chuẩn. Tôi chắc chắn tailcó thể được gỡ bỏ, nhưng sedfu của tôi không đủ mạnh để làm điều này.

Dường như với tôi, giải pháp này không dễ mang theo vì nó không hoạt động trên OS X. :(


Tôi nhận được sed: invalid option -- 'E'trên bash 3.2.51 và tcsh 6.15.00
craq

2

Giải pháp của tôi:

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

Điều này nên được di động trên các nền tảng và vỏ khác nhau. Nó sử dụng psnhư các giải pháp khác, nhưng nó không dựa vào sedhoặc awklọc rác từ đường ống vàps chính nó để vỏ luôn luôn là mục cuối cùng. Bằng cách này, chúng ta không cần phải dựa vào các biến PID không di động hoặc chọn ra các dòng và cột phù hợp.

Tôi đã thử nghiệm trên Debian và macOS với Bash, Z shell ( zsh) và fish (không hoạt động với hầu hết các giải pháp này mà không thay đổi biểu thức dành riêng cho cá, vì nó sử dụng biến PID khác nhau).


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

Từ Làm thế nào để bạn biết vỏ hiện tại của bạn là gì? .


3
Đó không phải là quá trình cha mẹ - đó là quá trình hiện tại.
Tạm dừng cho đến khi có thông báo mới.

7
Sử dụng grep $$là không đáng tin cậy. ps -ef | awk -v pid=$$ '$2==pid { print $8 }'là tốt hơn, nhưng tại sao không chỉ sử dụng ps -p $$?
musiphil

1

Trên Mac OS X (và FreeBSD):

ps -p $$ -axco command | sed -n '$p' 

2
Đã thử điều này trong khi sử dụng zsh, và nó đã cho tôi -bash.
dùng137369

Trên hệ thống của tôi (bây giờ), đã được thử nghiệm với bash và dash, lần trở lại này mutt...: -b
F. Hauri

1

Cắt xén PID từ đầu ra của "ps" là không cần thiết, bởi vì bạn có thể đọc dòng lệnh tương ứng cho bất kỳ PID nào từ cấu trúc thư mục / Proc:

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

Tuy nhiên, điều đó có thể không tốt hơn chỉ đơn giản là:

echo $0

Về việc chạy một shell thực sự khác với tên chỉ ra, một ý tưởng là yêu cầu phiên bản từ shell sử dụng tên bạn đã nhận trước đó:

<some_shell> --version

sh dường như thất bại với mã thoát 2 trong khi những người khác cung cấp một cái gì đó hữu ích (nhưng tôi không thể xác minh tất cả vì tôi không có chúng):

$ sh --version
sh: 0: Illegal option --
echo $?
2

1

Đây không phải là một giải pháp rất sạch sẽ, nhưng nó làm những gì bạn muốn.

# 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

Bây giờ bạn có thể sử dụng $(getshell) --version.

Mặc dù vậy, công việc này chỉ hoạt động trên các vỏ giống như KornShell (ksh).


1
"Tuy nhiên, công việc này chỉ hoạt động trên các vỏ giống như ksh." Bạn đang nói tôi phải xác minh vỏ trước khi chạy cái này? Hmm ...
jpaugh 17/8/2016

@jpaugh, danh sách phải được hỗ trợ bằng vỏ nguồn mã này, mà không phải là trường hợp cho dash, yashvv Thông thường, nếu bạn đang sử dụng bash, zsh, ksh, bất cứ điều gì - bạn không nên quan tâm đến những việc như vậy.
theoden8

Vì vậy, bạn đang đếm bash là "giống như ksh"? Hiểu rồi. Điều đó có ý nghĩa hơn
jpaugh

@jpaugh, ồ, đó là điều tôi muốn nói vì kshbộ tính năng chủ yếu là một tập hợp các bashtính năng (mặc dù chưa kiểm tra kỹ điều này).
theoden8

1

Thực hiện như sau để biết liệu shell của bạn có đang sử dụng Dash / Bash hay không.

ls –la /bin/sh:

  • nếu kết quả là /bin/sh -> /bin/bash==> Sau đó, shell của bạn đang sử dụng Bash.

  • nếu kết quả là /bin/sh ->/bin/dash==> Sau đó, shell của bạn đang sử dụng Dash.

Nếu bạn muốn thay đổi từ Bash thành Dash hoặc ngược lại, hãy sử dụng mã dưới đây:

ln -s /bin/bash /bin/sh (đổi vỏ thành Bash)

Lưu ý : Nếu lệnh trên dẫn đến lỗi, / bin / sh đã tồn tại, hãy xóa / bin / sh và thử lại.


0

Và tôi đã nghĩ ra cái này

sed 's/.*SHELL=//; s/[[:upper:]].*//' /proc/$$/environ

Điều này sẽ chỉ hoạt động trên Linux ! Không phải MacOS, cũng không phải BSD !!
F. Hauri

-1

Vui lòng sử dụng lệnh dưới đây:

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

Đầu tiên là vô nghĩa, echo $SHELLlàm những gì bạn đang cố gắng làm và làm nó tốt. Thứ hai cũng không tốt, vì $SHELLbiến môi trường chứa shell mặc định cho người dùng hiện tại, không phải shell hiện đang chạy. Nếu tôi có ví dụ bashđược đặt làm shell mặc định, hãy thực thi zshecho $SHELLnó sẽ in bash.
David Ferenczy Rogožan

Bạn đúng Dawid Ferenczy, Chúng tôi có thể sử dụng lệnh ps để xác định shell hiện tại. [# ps -p $$ | đuôi -1 | awk '{in $ 4}'].
Ranjithkumar T

echo $SHELLcó thể là rác: ~ $ echo $SHELL /bin/zsh ~ $ bash bash-4.3$ echo $SHELL /bin/zsh bash-4.3$
SaltwaterC

-2

Cái này hoạt động tốt trên Red Hat Linux (RHEL), macOS, BSD và một số AIXes :

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

cách khác, cái sau đây cũng sẽ hoạt động nếu pstree có sẵn,

pstree | egrep $$ | awk 'NR==2{print $NF}'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.