작업중인 현재 셸을 확인하는 방법은 무엇입니까?
현재 작업중인 셸을 어떻게 확인할 수 있습니까?
ps
명령 의 출력 만으로도 충분합니까?
이 작업을 다양한 UNIX 버전에서 어떻게 수행 할 수 있습니까?
현재 셸의 실행 파일 이름 을 찾는 방법에는 세 가지가 있습니다 .
쉘의 실행 파일이
/bin/sh
실제로 이름이 변경된bash
경우 (자주 발생하는) 세 가지 접근 방식 모두 속일 수 있습니다 .따라서
ps
출력이 수행 되는지 여부에 대한 두 번째 질문은 " 항상은 아님 "으로 대답됩니다 .echo $0
-프로그램 이름을 인쇄합니다 ... 쉘의 경우 실제 쉘입니다.ps -ef | grep $$ | grep -v grep
-실행중인 프로세스 목록에서 현재 프로세스 ID를 찾습니다. 현재 프로세스가 셸이므로 포함됩니다.ps
셸의 프로세스 ID와 동일한 번호 가 목록에 포함 된 다른 프로세스가있을 수 있으므로 이는 100 % 신뢰할 수 없습니다 . 특히 해당 ID가 작은 # 인 경우 (예 : 셸의 PID가 "5"이면 "java5"라는 프로세스를 찾을 수 있습니다.) 또는 동일한grep
출력 에서 "perl5" !). 이것은 쉘 이름에 의존 할 수 없다는 것 외에 "ps"접근 방식의 두 번째 문제입니다.echo $SHELL
-현재 쉘의 경로SHELL
는 모든 쉘 의 변수 로 저장됩니다 . 이것에 대한주의 사항은 쉘을 하위 프로세스로 명시 적으로 시작하면 (예 : 로그인 쉘이 아님) 대신 로그인 쉘의 값을 얻게된다는 것입니다. 가능하다면ps
또는$0
접근 방식을 사용하십시오 .
그러나 실행 파일이 실제 셸과 일치하지 않는 경우 (예 :
/bin/sh
실제로 bash 또는 ksh), 휴리스틱이 필요합니다. 다음은 다양한 쉘에 특정한 환경 변수입니다.$version
tcsh에 설정 됨$BASH
bash에 설정되어 있습니다.$shell
(소문자)는 csh 또는 tcsh에서 실제 쉘 이름으로 설정됩니다.$ZSH_NAME
zsh에 설정 됨KSH가 보유
$PS3
하고$PS4
설정된 정상 반면 본 셸 (sh
)만을 보유$PS1
하고$PS2
세트. 이것은 일반적으로 보인다 가장 어려운 구별하기 - 사이 envionmental 변수의 전체 세트의 차이점을sh
하고ksh
우리는 솔라리스 회양목에 설치 한이다$ERRNO
,$FCEDIT
,$LINENO
,$PPID
,$PS3
,$PS4
,$RANDOM
,$SECONDS
,$TMOUT
.
ps -p $$
어디서나 솔루션을 포함하는 것을 작동해야 ps -ef
하고 grep
(지원하는 유닉스 변종에서 수행 을 위해 POSIX 옵션을ps
) 다른 곳에서 나타날 수있는 일련의 숫자에 대한 grepping에 의해 도입 된 잘못된 반응으로 고생하지 않습니다.
시험
ps -p $$ -oargs=
또는
ps -p $$ -ocomm=
사용자가 bash로 스크립트를 호출하고 있는지 확인하려면 다음을 수행하십시오.
if [ ! -n "$BASH" ] ;then echo Please run this script $0 with bash; exit 1; fi
당신은 시도 할 수 있습니다:
ps | grep `echo $$` | awk '{ print $4 }'
또는:
echo $SHELL
$SHELL
항상 현재 셸을 표시 할 필요는 없습니다. 호출 할 기본 셸만 반영합니다.
위의 내용을 테스트하기 위해 Say bash
가 기본 셸이고 try echo $SHELL
이고 같은 터미널에서 다른 셸 (예 : ksh)로 들어가서 try $SHELL
, 두 경우 모두 결과가 bash로 표시됩니다.
현재 쉘의 이름을 얻으려면 다음을 사용 cat /proc/$$/cmdline
하여 쉘 실행 파일의 경로를 사용하십시오.readlink /proc/$$/exe
ps는 가장 신뢰할 수있는 방법입니다. SHELL 환경은 설정이 보장되지 않으며 설정되어 있어도 쉽게 스푸핑 될 수 있습니다.
현재 셸을 찾는 간단한 방법이 있습니다. 임의의 문자열 (명령이 아님)을 입력하십시오. 실패하고 "찾을 수 없음"오류를 반환하지만 줄 시작 부분에 어떤 쉘인지 알려줍니다.
ksh: aaaaa: not found [No such file or directory]
bash: aaaaa: command not found
This will give always the actual shell used - gets the name of the actual executable and not shell name (i.e. ksh93
instead of ksh
etc.) For /bin/sh
will show the actual shell used: i.e. dash
ls -l /proc/$$/exe | sed 's%.*/%%'
I know that here are many who say ls
output should be newer processed but what is the probability you'll have a shell you are using named with special characters or placed in a directory named with special characters? If still this is the case, here are plenty other examples doing it differently.
I have tried many different approaches and the best one for me is:
ps -p $$
It also works under Cygwin and cannot produce false positives as PID grepping. With some cleaning, it outputs just an executable name (under Cygwin with path):
ps -p $$ | tail -1 | awk '{print $NF}'
You can create a function so you don't have to memorize it:
# print currently active shell
shell () {
ps -p $$ | tail -1 | awk '{print $NF}'
}
...and then just execute shell
.
Tested under Debian and Cygwin.
My variant on printing the parent process.
ps -p $$ | awk '$1 == PP {print $4}' PP=$$
Why run unnecessary applications, when 'awk' can do it for you?
Provided that your /bin/sh
supports the POSIX standard and your system has the lsof
command installed - a possible alternative to lsof
could in this case be pid2path
- you can also use (or adapt) the following script that prints full paths:
#!/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}'
echo $$ # Gives the Parent Process ID
ps -ef | grep $$ | awk '{print $8}' #use the PID to see what the process is.
None of answers worked with fish
shell (it doesn't have variables $$
or $0
).
This works for me (tested on sh
, bash
, fish
, ksh
, csh
, true
, tcsh
, and zsh
; openSUSE 13.2):
ps | tail -n 4 | sed -E '2,$d;s/.* (.*)/\1/'
This command outputs string like bash
. I'm using here only ps
, tail
, and sed
(without GNU extesions; try to add --posix
to check it). They all are standard POSIX commands. I'm sure tail
can be removed, but my sed
fu is not strong enough to do this.
It seems to me, that this solution is not very portable as it doesn't work on OS X. :(
There are many ways to find out the shell and its corresponding version. Here are few which worked for me.
Straight forward
- $> echo $0 (Gives you the program name. In my case the output was -bash)
- $> $SHELL (This takes you into the shell and in the prompt you get the shell name and version. In my case bash3.2$ )
- $> echo $SHELL (This will give you executable path. In my case /bin/bash)
- $> $SHELL --version (This will give complete info about the shell software with licence type)
Hackish approach
$> ******* (Type a set of random characters and in the output you will get the shell name. In my case -bash: chapter2-a-sample-isomorphic-app: command not found)
On Mac OS X (& FreeBSD):
ps -p $$ -axco command | sed -n '$p'
If you just want to check that you are running (a particular version of) Bash, the best way to do so is to use the $BASH_VERSINFO
array variable. As a (readonly) array variable it cannot be set in the environment, so you can be sure it is coming (if at all) from the current shell. However, since Bash has different behavior when invoked as sh
, you do also need to check the $BASH
environment variable ends with /bash
.
In a script I wrote that uses function names with -
(not underscore) and depends on associative arrays (added in Bash 4), I have the following sanity check (with helpful user error message):
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
You could omit the somewhat paranoid functional check for features in the first case, and just assume that future bash versions would be compatible.
Grepping PID from output of "ps" is not needed because you can read respective command line for any PID from /proc directory structure:
echo $(cat /proc/$$/cmdline)
However, that might not be any better than just simply:
echo $0
About running actually different shell than the name indicates, one idea is to request version from shell using the name you got previously:
<some_shell> --version
sh seems to fail with exit code 2 while others give something useful (but I am not able to verify all since I don't have them):
$ sh --version
sh: 0: Illegal option --
echo $?
2
This is not very clean solution, but does what you want.
I realise that the answer is a bit late in this good old 2015, but...
#MUST BE SOURCED..
getshell() {
local shell="`ps -p $$ | tail -1 | awk '{print $4}'`"
shells_array=(
# It is important that the shells are listed by the decrease of their length name.
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
Now you can use $(getshell) --version.
This works, though, only on ksh-like shells.
My solution:
ps -o command | grep -v -e "\<ps\>" -e grep -e tail | tail -1
This should be portable across different platforms and shells. It uses ps
like other solutions, but it doesn't rely on sed
or awk
and filters out junk from piping and ps
itself so that the shell should always be the last entry. This way we don't need to rely on non-portable PID variables or picking out the right lines and columns.
I've tested on Debian and MacOS with bash, zsh, and fish (which doesn't work with most of these solutions without changing the expression specifically for fish, because it uses a different PID variable).
Do the following to know, whether your Shell is using DASH/BASH.
1) ls –la /bin/sh, if the result is /bin/sh ->/bin/bash ==> Then your shell is using BASH.
if the result is /bin/sh ->/bin/dash ==> Then your shell is using DASH.
If you want to change from BASH to DASH or vice-versa, use the below code ln -s /bin/bash /bin/sh (change shell to BASH)
NOTE: If the above command results in a error saying, /bin/sh already exists, remove the /bin/sh and try again.
Kindly use below command:
# ps -p $$ | tail -1 | awk '{print $4}'
This one works well on RHEL, MacOS, BSD and some AIXes
ps -T $$ | awk 'NR==2{print $NF}'
alternatively, following one should also work if pstree is available,
pstree | egrep $$ | awk 'NR==2{print $NF}'
참고URL : https://stackoverflow.com/questions/3327013/how-to-determine-the-current-shell-im-working-on
'developer tip' 카테고리의 다른 글
Java assert 키워드의 기능은 무엇이며 언제 사용해야합니까? (0) | 2020.10.03 |
---|---|
ConcurrentHashMap과 Collections.synchronizedMap (Map)의 차이점은 무엇입니까? (0) | 2020.10.03 |
단위 테스트에 대한 합리적인 코드 커버리지 %는 무엇이며 그 이유는 무엇입니까? (0) | 2020.10.03 |
멀티 코어 머신의 Node.js (0) | 2020.10.03 |
UTF8 인코딩을 사용하여 Excel에서 CSV로 (0) | 2020.10.03 |