Làm thế nào để kiểm tra shell nào tôi đang sử dụng trong một thiết bị đầu cuối?


69

Làm thế nào để kiểm tra những gì tôi đang sử dụng trong một thiết bị đầu cuối? Shell tôi đang sử dụng trong MacOS là gì?


2
@xenoterracide: ít nhất là unix.stackexchange.com/questions/3645/iêu . Câu trả lời của geekizard hoàn chỉnh hơn, vì vậy tôi đã bỏ phiếu để đóng câu hỏi trước đó.
Gilles

1
tiếng vang $ SHELL, không?
thế giới vô tội

@ thế giới vô tội Không, echo #SHELLkhông hoàn toàn như vậy. Xem số 3 trong câu trả lời của geekizard .
Basil Bourque

Tôi không chắc chắn rằng "vỏ" có một ý nghĩa được xác định rõ. Ví dụ, bạn có thể chạy xterm -e /bin/cat nhưng tôi không vui khi gọi /bin/catshell.
Stilenkevitch Basile

Ngoài ra, một số shell (như scsh ) không sử dụng cú pháp POSIX shell.
Basile Starynkevitch

Câu trả lời:


71

Một số cách, từ hầu hết đến đáng tin cậy nhất (và hầu hết đến "nặng" nhất):

  1. ps -p$$ -ocmd=. (Trên Solaris, điều này có thể cần phải fnamethay thế cmd. Trên OSX và trên BSD nên commandthay thế cmd.)
  2. Kiểm tra $BASH_VERSION, $ZSH_VERSIONvà các biến shell cụ thể khác.
  3. Kiểm tra $SHELL; đây là giải pháp cuối cùng, vì nó chỉ định shell mặc định của bạn và không nhất thiết là shell hiện tại .

4
Bạn cũng nên đề cập $0?
Mikel

Tôi không thích $0vì nó phức tạp hơn: (1) nó có thể chỉ là tên cơ sở, (2) nó có thể có '-' ở mặt trước để chỉ định nó làm vỏ đăng nhập.
geekizard

ps -p$$ -ocmd=""là đẹp hơn :-)
asoundmove

1
@geekizard: có thể vậy, nhưng $0dường như vẫn hữu ích hơn $SHELL: bạn có đồng ý không? Bạn luôn có thể chuyển nó qua sedđể loại bỏ '-'.
iconoclast

2
Nếu bạn đang chạy tcsh, $tcsh$versionsẽ được đặt. Đây là các biến shell, không phải biến môi trường. Nếu bạn đang chạy phiên bản không phải là tcsh csh, tôi không nghĩ có bất kỳ biến số đặc biệt nào. Và tất nhiên, cú pháp được sử dụng để kiểm tra các biến khác nhau giữa csh / tcsh một mặt và mặt khác sh / ksh / bash / zsh.
Keith Thompson

41

Tôi đã thấy rằng các tác phẩm sau trong bốn trình bao tôi đã cài đặt trên hệ thống của mình (bash, dash, zsh, csh):

$ ps -p $$

Sau đây hoạt động trên zsh, bash và dash, nhưng không phải trên csh:

$ echo $0

2
Cũng không hoạt động trên cá.
Ron E

Tôi nghĩ rằng câu trả lời của @ jiliagre có lẽ tôi sẽ sử dụng ngày hôm nay. Trên cá %selfcó thể được sử dụng thay cho$$
Steven D

8

Vì câu hỏi yêu cầu trình bao được sử dụng và không nói về các đối số tiềm năng được truyền cho nó, đây là một cách để tránh hiển thị chúng:

$ ps -o comm= -p $$
ksh93 

6

Lưu ý về một số triển khai nhẹ hơn (điện thoại Android, busybox, v.v.): pskhông phải lúc nào cũng có hỗ trợ cho -pchuyển đổi, nhưng bạn có thể thực hiện tìm kiếm bằng một lệnh như thế nào ps | grep "^$$ ". ( grepRegex này sẽ xác định duy nhất PID, do đó sẽ không có bất kỳ kết quả dương tính giả nào.


7
ps | grep $$vẫn có thể đưa ra dương tính giả nếu, ví dụ, quy trình hiện tại của bạn là 1234và có một quy trình 12345.
Keith Thompson

4

Có hai cách thực sự đơn giản:

  • Sử dụng lệnh ps :

    ps -o comm= $$

    hoặc là

    ps -h -o comm -p $$

    Ở đâu:

    • -hhoặc hoàn thành tất cả các tùy chọn với =việc không hiển thị bất kỳ tiêu đề.
    • -o commđể chỉ hiển thị tên cơ sở của quá trình ( bashthay vì /bin/bash).
    • -p <PID> danh sách chỉ xử lý với danh sách biểu mẫu PID được cung cấp.
  • Sử dụng hệ thống tập tin giả / thông tin quy trình / Proc :

    cat /proc/$$/comm

    Tùy chọn này hoạt động chính xác như pslệnh trên.

    hoặc là

    readlink /proc/$$/exe

    /proc/PID/exeLiên kết này đến tệp đang được thực thi, trong trường hợp này sẽ trỏ đến / bin / bash, / bin / ksh, v.v.

    Để chỉ nhận được tên của vỏ, bạn chỉ có thể sử dụng

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

    Đây là tùy chọn duy nhất sẽ luôn cho kết quả tương tự ngay cả khi bạn đang ở trong tập lệnh, mã nguồn hoặc thiết bị đầu cuối, dưới dạng liên kết đến tệp nhị phân của trình thông dịch shell đang sử dụng.

    Cảnh báo Bạn phải lưu ý rằng điều này sẽ hiển thị nhị phân cuối cùng, vì vậy ksh có thể được liên kết với ksh93 hoặc sh để bash.

Việc sử dụng /procthực sự hữu ích thông qua /proc/self, liên kết đến PID của lệnh hiện tại.


3

Tổng hợp tất cả các câu trả lời khác, tương thích với Mac (comm), Solaris (fname) và Linux (cmd):

ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1

cái này cho tôi tên thư mục hiện tại của tôi; Ngoài ra, dưới cshtcshnó mang lại cho tôiAmbiguous output redirect.
iconoclast

2

Nếu bạn đã lưu nó trong các biến môi trường của mình, bạn có thể sử dụng như sau:

echo $SHELL

Điều đó rất có thể sẽ trả về tên đường dẫn của trình bao thực thi của trình đăng nhập của bạn. Không có gì chắc chắn rằng shell đăng nhập là những gì bạn hiện đang chạy.
Kusalananda

1

Các pid của shell đang chạy được đưa ra bởi var $$ (trong hầu hết các shell).

whichsh="`ps -o pid,args| awk '$1=='"$$"'{print $2}'`"
echo "$whichsh"

Sử dụng backticks để làm cho jsh (Heirlomm shell) hoạt động.

Trong nhiều shell, thử nghiệm trực tiếp của các ps -o args= -p $$công trình, nhưng busybox ashthất bại trên đó (đã giải quyết).

Kiểm tra $1phải bằng để $$loại bỏ hầu hết các dương tính giả.

Cái cuối cùng ;:được sử dụng để giữ cho vỏ chạy cho ksh và zsh.

Các thử nghiệm trên nhiều hệ thống sẽ giúp ích, vui lòng đưa ra nhận xét nếu nó không hiệu quả với bạn.

Không hoạt động trong các cshloại vỏ.


Trên OS / X, trong các thử nghiệm của tôi, tôi nhận được ít nhất 3 dòng, một cho shell, một cho /usr/lib/dyld, một cho /private/var/db/dyld/dyld_shared_cache_x86_64.
Stéphane Chazelas

Có, hiện tại nó chỉ chọn các mục trong / bin và / usr / bin
Stéphane Chazelas

@ StéphaneChazelas Có lẽ bây giờ tốt hơn?

0

Tôi đặt ra $MYSHELLcho các thử nghiệm trong tương lai trong thuyết bất khả tri của mình ~/.aliases:

unset MYSHELL
if [ -n "$ZSH_VERSION" ] && type zstyle >/dev/null 2>&1; then        # zsh
  MYSHELL=`command -v zsh`
elif [ -x "$BASH" ] && shopt -q >/dev/null 2>&1; then                # bash
  MYSHELL=`command -v bash`
elif [ -x "$shell" ] && which setenv |grep builtin >/dev/null; then  # tcsh
  echo "DANGER: this script is likely not compatible with C shells!"
  sleep 5
  setenv MYSHELL "$shell"
fi

# verify
if [ ! -x "$MYSHELL" ]; then
  MYSHELL=`command -v "$(ps $$ |awk 'NR == 2 { print $NF }')"`
  [ -x "$MYSHELL" ] || MYSHELL="${SHELL:-/bin/sh}"  # default if verify fails
fi

Các tcshphần có thể không khôn ngoan để cuộn thành một kịch bản POSIX kiểu vì nó quá hoàn toàn khác nhau (như vậy, cảnh báo và tạm dừng thứ hai năm). (Đối với một, các cshkiểu vỏ không thể làm 2>/dev/nullhoặc >&2, như đã lưu ý trong phần lập trình Csh nổi tiếng được coi là có hại .)


-1

Bạn có thể chỉ cần sử dụng echo $0lệnh để kiểm tra shell nào bạn đang sử dụng và <name_of_the_shell> --versionkiểm tra phiên bản của shell. (ví dụ. bash --version).


Steven D đã đề cập đến nó :)
lese

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.