736

現在作業しているシェルを確認するにはどうすればよいですか?

コマンドの出力psだけで十分でしょうか?

Unixのさまざまなフレーバーでこれをどのように行うことができますか?

4

28 に答える 28

895
  • 現在のシェルの実行可能ファイルの名前を見つけるには、次の3つの方法があります。

    シェルの実行可能ファイルがである場合、3つのアプローチすべてがだまされる可能性があることに注意してください。ただし、たとえば、/bin/sh実際には名前が変更されています(これは頻繁に発生します)。bash

    したがって、ps出力が機能するかどうかの2番目の質問は、「常にではない」で答えられます。

    1. echo $0-プログラム名を出力します...シェルの場合は実際のシェルです。

    2. ps -ef | grep $$ | grep -v grep-これにより、実行中のプロセスのリストで現在のプロセスIDが検索されます。現在のプロセスはシェルであるため、含まれます。

      リストにシェルのプロセスIDと同じ番号が含まれている他のプロセスがある可能性があるため、これは100%信頼できるわけではありませんps。特に、そのIDが小さい場合(たとえば、シェルのPIDが「5」の場合)、同じ出力の「java5」または「perl5」grep!)。これは、シェル名に依存できないことに加えて、「ps」アプローチの2番目の問題です。

    3. echo $SHELL-現在のシェルへのパスは、SHELL任意のシェルの変数として保存されます。これに関する注意点は、シェルをサブプロセスとして明示的に起動した場合(たとえば、ログインシェルではない場合)、代わりにログインシェルの値を取得することです。それが可能であれば、psまたは$0アプローチを使用してください。


  • ただし、実行可能ファイルが実際のシェルと一致しない場合(たとえば/bin/sh、実際にはbashまたはksh)、ヒューリスティックが必要です。さまざまなシェルに固有の環境変数を次に示します。

    • $versiontcshに設定されています

    • $BASHbashに設定されています

    • $shell(小文字)は、cshまたはtcshの実際のシェル名に設定されます

    • $ZSH_NAMEzshに設定されています

    • kshにはとが$PS3設定されてい$PS4ますが、通常のBourneシェル(sh$PS1にはとが$PS2設定されています。これは一般的に区別するのが最も難しいように思われます-Solarisboxenにインストールした環境変数のセット全体の唯一の違いは、、、、、、、、、、、およびです。shksh$ERRNO$FCEDIT$LINENO$PPID$PS3$PS4$RANDOM$SECONDS$TMOUT

于 2010-07-24T21:37:34.633 に答える
117

ps -p $$

ps -efを含むソリューションが( POSIXオプションgrepをサポートするUnixバリアントで)実行する場所であればどこでも機能するはずであり、他の場所に表示される可能性のある一連の数字のgrepingによって導入される誤検知の影響を受けません。ps

于 2010-07-24T22:09:37.047 に答える
51

試す

ps -p $$ -oargs=

また

ps -p $$ -ocomm=
于 2012-06-19T08:59:32.270 に答える
40

ユーザーがBashでスクリプトを呼び出していることを確認したいだけの場合:

if [ -z "$BASH" ] ;then echo "Please run this script $0 with bash"; exit 1; fi
于 2013-03-31T16:54:15.197 に答える
24

あなたが試すことができます:

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

または:

echo $SHELL
于 2010-07-24T21:38:44.137 に答える
21

$SHELL常に現在のシェルを表示する必要はありません。呼び出されるデフォルトのシェルのみを反映します。

上記をテストするには、たとえばbashデフォルトのシェルを試しecho $SHELLてから、同じターミナルで他のシェル(KornShell(ksh)など)にアクセスして試してください$SHELL。どちらの場合も、結果はbashとして表示されます。

現在のシェルの名前を取得するには、を使用しcat /proc/$$/cmdlineます。そして、によるシェル実行可能ファイルへのパスreadlink /proc/$$/exe

于 2012-10-15T11:45:43.417 に答える
13

シェルとそれに対応するバージョンを見つける方法はたくさんあります。ここに私のために働いたいくつかがあります。

簡単

  1. $> echo $ 0(プログラム名を指定します。私の場合、出力は-bashでした。)
  2. $> $ SHELL(これによりシェルが表示され、プロンプトでシェルの名前とバージョンが表示されます。私の場合はbash3.2 $です。)
  3. $> echo $ SHELL(これにより、実行可能パスが提供されます。私の場合は/ bin / bashです。)
  4. $> $ SHELL --version(これにより、ライセンスタイプのシェルソフトウェアに関する完全な情報が提供されます)

ハックなアプローチ

$> *******(ランダムな文字のセットを入力すると、出力にシ​​ェル名が表示されます。私の場合は-bash:chapter2-a-sample-isomorphic-app:コマンドが見つかりません

于 2017-09-19T07:30:27.827 に答える
11

psは最も信頼できる方法です。SHELL環境変数は、設定が保証されているわけではなく、設定されている場合でも、簡単になりすますことができます。

于 2010-07-24T21:39:39.810 に答える
11

現在のシェルを見つけるための簡単なトリックがあります。ランダムな文字列を入力するだけです(これはコマンドではありません)。失敗して「見つかりません」エラーが返されますが、行の先頭に、それがどのシェルであるかが示されます。

ksh: aaaaa: not found [No such file or directory]
bash: aaaaa: command not found
于 2015-12-09T15:34:54.403 に答える
7

私は多くの異なるアプローチを試しましたが、私にとって最良のアプローチは次のとおりです。

ps -p $$

また、Cygwinでも機能し、PIDgreppingとして誤検知を生成することはできません。いくつかのクリーニングを行うと、実行可能ファイル名(パス付きのCygwinの下)のみが出力されます。

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

関数を作成して、覚える必要がないようにすることができます。

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

...そして実行するだけshellです。

DebianとCygwinでテストされました。

于 2014-10-14T11:57:50.520 に答える
6

以下は、常に実際に使用されるシェルを示します。シェル名ではなく、実際の実行可能ファイルの名前を取得します(つまり、などksh93の代わりにksh)。の場合/bin/sh、実際に使用されているシェルが表示されdashます。

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

出力は決して処理されるべきではないと言う人がたくさんいることは知っていlsますが、特殊文字で名前が付けられた、または特殊文字で名前が付けられたディレクトリに配置されたシェルを使用する確率はどれくらいですか?それでもそうであれば、別の方法でそれを行う例は他にもたくさんあります。

Toby Speightが指摘しているように、これは同じことを達成するためのより適切でクリーンな方法です。

basename $(readlink /proc/$$/exe)
于 2014-06-16T22:44:25.323 に答える
5

親プロセスの印刷に関する私の変種:

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

AWKが実行できる場合は、不要なアプリケーションを実行しないでください。

于 2015-08-25T13:37:28.490 に答える
4

がPOSIX標準を/bin/shサポートし、システムにlsofコマンドがインストールされている場合(この場合の代替案lsofpid2path、フルパスを出力する次のスクリプトを使用(または適合)することもできます。

#!/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}'
于 2013-03-20T17:30:04.863 に答える
3

私の解決策:

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

これは、さまざまなプラットフォームやシェル間で移植可能である必要があります。他のソリューションと同じように使用しますが、またはにps依存せず、配管やそれ自体からジャンクを除外するため、シェルは常に最後のエントリになります。このように、移植性のないPID変数に依存したり、適切な行と列を選択したりする必要はありません。sedawkps

私はDebianとmacOSでBash、Zシェルzsh)、およびをテストしました(これは、異なるPID変数を使用するため、特に魚の式を変更しない限り、これらのソリューションのほとんどでは機能しません)。

于 2017-05-17T23:13:09.367 に答える
2

Bash(の特定のバージョン)を実行していることを確認したいだけの場合は、$BASH_VERSINFO配列変数を使用するのが最善の方法です。(読み取り専用)配列変数として、環境内で設定することはできないため、現在のシェルからのものであるかどうかを確認できます。

ただし、Bashをとして呼び出すと動作が異なるため、環境変数が。で終わるshことも確認する必要があります。$BASH/bash

-(アンダースコアではなく)関数名を使用し、連想配列(Bash 4で追加)に依存する私が書いたスクリプトでは、次の健全性チェックがあります(役立つユーザーエラーメッセージが表示されます)。

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

最初のケースでは、機能のやや偏狭な機能チェックを省略して、将来のBashバージョンに互換性があると想定することができます。

于 2014-08-11T17:38:09.670 に答える
1
echo $$ # Gives the Parent Process ID 
ps -ef | grep $$ | awk '{print $8}' # Use the PID to see what the process is.

から現在のシェルが何であるかをどうやって知るのですか?

于 2010-07-24T21:41:25.477 に答える
1

いずれの回答もfishシェルでは機能しませんでした(変数$$または$0)はありません。

これは私にとってはうまくいきます(、、、、、、、、、および; openSUSE 13.2shでテスト済みbash) :fishkshcshtruetcshzsh

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

このコマンドは、のような文字列を出力しますbash。ここでは、、、およびのみを使用してpstailますsed(GNU拡張機能なし。追加--posixして確認してください)。これらはすべて標準のPOSIXコマンドです。確かtailに取り除くことができますが、私のsedfuはこれを行うのに十分な強さではありません。

このソリューションはOSXでは機能しないため、移植性が低いように思われます。:(

于 2014-09-13T09:07:50.537 に答える
1

これはあまりクリーンなソリューションではありませんが、必要なことを実行します。

# 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

これで、を使用できます$(getshell) --version

ただし、これはKornShellのようなシェル(ksh)でのみ機能します。

于 2015-07-09T18:42:56.277 に答える
1

シェルがDash/Bashを使用しているかどうかを確認するには、次の手順を実行します。

ls –la /bin/sh

  • 結果が/bin/sh -> /bin/bash==>の場合、シェルはBashを使用しています。

  • 結果が/bin/sh ->/bin/dash==>の場合、シェルはDashを使用しています。

BashからDashに、またはその逆に変更する場合は、次のコードを使用します。

ln -s /bin/bash /bin/sh(シェルをBashに変更します)

:上記のコマンドで/ bin / shが既に存在するというエラーが発生した場合は、/ bin/shを削除して再試行してください。

于 2017-12-14T08:12:15.190 に答える
1

私はNahuelFouilleulのソリューションが特に好きですが、組み込みのBashシェルを使用してUbuntu18.04で次のバリアントを実行する必要がありました。

bash -c 'shellPID=$$; ps -ocomm= -q $shellPID'

一時変数がない場合shellPID、たとえば次のようになります。

bash -c 'ps -ocomm= -q $$'

私のために出力psします。たぶん、あなたはすべて非対話型モードを使用しているわけではありません、そしてそれは違いを生みますか?

于 2021-03-24T17:50:52.463 に答える
0

Mac OS X(およびFreeBSD)の場合:

ps -p $$ -axco command | sed -n '$p' 
于 2010-07-25T18:02:39.813 に答える
0

/ procディレクトリ構造から任意のPIDのそれぞれのコマンドラインを読み取ることができるため、「ps」の出力からPIDを取得する必要はありません。

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

ただし、それは単に次のことよりも優れているとは限りません。

echo $0

名前が示すものとは実際に異なるシェルを実行することについて、1つのアイデアは、以前に取得した名前を使用してシェルからバージョンを要求することです。

<some_shell> --version

sh他の人が何か役に立つものを与える間、終了コード2で失敗するようです(しかし、私はそれらを持っていないので、私はすべてを確認することができません):

$ sh --version
sh: 0: Illegal option --
echo $?
2
于 2014-10-30T18:16:40.280 に答える
0

varで取得してみませんか$SHELL。単純なsedでパスを削除できます。

$ echo $SHELL | sed -E 's/^.*\/([aA-zZ]+$)/\1/g'
bash

MacOS、Ubuntu、CentOSでテスト済み

于 2021-06-03T09:52:36.947 に答える
0

1つの方法は次のとおりです。

ps -p $$ -o exe=

これは、IMOを使用するよりも、-o argsまたは-o comm別の回答で提案されているように優れています(これらは/bin/sh、ダッシュやbashなどの特定のシェルを指す場合などのシンボリックリンクを使用する場合があります)。

上記は実行可能ファイルのパスを返しますが、/ usr-mergeのために、複数のパス(例/bin/bash /usr/bin/bash)をチェックする必要がある場合があることに注意してください。

また、上記は完全にPOSIX互換ではないことに注意してください(POSIX psにはありませんexe)。

于 2021-06-09T01:13:32.657 に答える
-1

以下のコマンドをご利用ください。

ps -p $$ | tail -1 | awk '{print $4}'
于 2013-10-22T10:26:08.373 に答える
-1

そして、私はこれを思いついた

sed 's/.*SHELL=//; s/[[:upper:]].*//' /proc/$$/environ
于 2020-02-05T09:52:19.800 に答える
-1

使用できますecho $SHELL|sed "s/\/bin\///g"

于 2021-10-10T18:39:38.423 に答える
-2

これは、Red Hat Linux(RHEL)、macOS、BSD、および一部のAIXでうまく機能します。

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

または、 pstreeが利用可能な場合は、次のものも機能するはずです。

pstree | egrep $$ | awk 'NR==2{print $NF}'
于 2017-12-11T16:38:00.717 に答える