it-swarm-vi.com

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

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

73
user5837

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 là fname thay vì cmd. Trên OSX và trên BSD nên là command thay vì cmd.)
  2. Kiểm tra $BASH_VERSION, $ZSH_VERSION và các biến cụ thể khác của Shell.
  3. Kiểm tra $Shell; đây là giải pháp cuối cùng, vì nó chỉ định mặc định Shell của bạn và không nhất thiết phải là hiện tại Shell.
75
geekosaur

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
43
Steven D

Vì câu hỏi yêu cầu Shell 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 
8
jlliagre

Lưu ý về một số triển khai nhẹ hơn (điện thoại Android, busybox, v.v.): ps không phải lúc nào cũng có hỗ trợ cho -p chuyển đổi, nhưng bạn có thể thực hiện tìm kiếm bằng một lệnh như ps | grep "^$$ ". (grep regex 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.

6
palswim

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:

    • -h hoặc hoàn thành tất cả các tùy chọn với = vì 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 (bash thay 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 /Proc xử lý hệ thống tệp giả thông tin:

    cat /proc/$$/comm
    

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

    hoặc là

    readlink /proc/$$/exe
    

    Điều này /proc/PID/exe liên kết đế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 Shell, 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 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 /proc thực sự hữu ích thông qua /proc/self, liên kết đến PID của lệnh hiện tại.

5
David Goitia

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
3
sebastien

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
2
jasonleonhard

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, bài kiểm tra trực tiếp của ps -o args= -p $$ hoạt động, nhưng busybox ash thất bại về điều đó (đã giải quyết).

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

Cuối cùng ;: được sử dụng để giữ Shell 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 csh loại vỏ.

1
user79743

Tôi đặt $MYSHELL cho các thử nghiệm trong tương lai trong thuyết bất khả tri của tôi ~/.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

Phần tcsh dường như không được chuyển thành tập lệnh kiểu POSIX vì nó rất khác nhau (do đó cảnh báo và tạm dừng năm giây). (Đối với một, các vỏ kiểu csh- không thể làm 2>/dev/null hoặc là >&2, như đã lưu ý trong phần nổi tiếng Lập trình Csh được coi là có hại rant.)

0
Adam Katz