현재 사용 중인 대화형 셸을 확인하는 방법(명령줄)
작업 중인 현재 셸을 확인하려면 어떻게 해야 합니까?
(력)의 은?ps명령만으로 충분합니까?
다양한 버전의 유닉스에서 어떻게 이것을 할 수 있습니까?
현재 셸의 실행 파일 이름을 찾는 방법은 세 가지가 있습니다.
셸의 실행 파일이 다음과 같은 경우 세 가지 접근 방식을 모두 속일 수 있습니다.
/bin/sh하지만 정말로 이름이 바뀌었습니다.bash예를 들어, 자주 발생합니다.그러므로 당신의 두 번째 질문은
ps출력은 "항상은 아님"으로 응답하면 됩니다.echo $0프로그램 이름을 인쇄합니다...껍질의 경우에는 실제 껍질입니다.ps -ef | grep $$ | grep -v grep실행 중인 프로세스 목록에서 현재 프로세스 ID를 찾습니다.현재 공정이 셸이기 때문에 포함될 것입니다.이것은 100% 신뢰할 수 있는 것은 아닙니다. 왜냐하면 당신은 다음과 같은 다른 프로세스가 있을 수 있기 때문입니다.
ps한 숫자를 하며, 숫자인 ) 한 " " 수 . 특히 ID가 작은 숫자인 경우(예: 셸의 PID가 "5"인 경우) 동일한 숫자에서 "java5" 또는 "perl5"라는 프로세스를 찾을 수 있습니다.grep출력!).이것은 셸 이름에 의존할 수 없는 것 외에도 "ps" 접근법의 두 번째 문제입니다.echo $SHELL경로는 셸재에경다로같음저이다니로 됩니다.SHELL모든 셸에 대한 변수.여기서 주의할 점은 하위 프로세스로 셸을 명시적으로 시작하면(예: 로그인 셸이 아님) 로그인 셸의 값이 대신 표시된다는 것입니다.가능한 경우 다음을 사용합니다.ps또는$0접근.
셸과하지 않는 경우 그나실파행예실셸않일는경지우하치과제이일러예경않:우(는▁if▁doesn▁(,지e):
/bin/sh실제로는 bash 또는 ksh)입니다. 휴리스틱이 필요합니다.다음은 다양한 셸에 특정한 환경 변수입니다.$versiontcshtcsh에됩니다.$BASH됨 »$shell또는 (으)로 셸 됩니다.$ZSH_NAME는 zshzsh에에 됩니다.hash has
$PS3그리고.$PS4세트, 반면에 일반 본 쉘 (sh)만 있습니다.$PS1그리고.$PS2set. 이것은 일반적으로 가장 구별하기 어려운 것처럼 보입니다 - 전체 환경 변수 집합의 유일한 차이입니다.sh그리고.kshis Solaris boxenis에 했습니다.$ERRNO,$FCEDIT,$LINENO,$PPID,$PS3,$PS4,$RANDOM,$SECONDS,그리고.$TMOUT.
ps -p $$
솔루션이 관련된 모든 곳에서 작동해야 합니다.ps -ef그리고.grep(에 대한 POSIX 옵션을 지원하는 모든 Unix 변형에 대해) 를 수행하고 다른 곳에 나타날 수 있는 일련의 숫자에 대한 그리핑을 통해 도입된 잘못된 긍정으로 인해 어려움을 겪지 않습니다.
해라
ps -p $$ -oargs=
또는
ps -p $$ -ocomm=
사용자가 Bash를 사용하여 스크립트를 호출하는지 확인하려는 경우:
if [ -z "$BASH" ]; then echo "Please run this script $0 with bash"; exit; fi
또는 참조
if [ -z "$BASH" ]; then exec bash $0 ; exit; fi
시도할 수 있습니다.
ps | grep `echo $$` | awk '{ print $4 }'
또는:
echo $SHELL
$SHELL항상 현재 셸을 표시할 필요는 없습니다.호출할 기본 셸만 반영합니다.
위의 내용을 테스트하려면 다음과 같이 하십시오.bash셸입니다. 를 사용해 보십시오. 시도해 보십시오.echo $SHELL그런 다음 동일한 터미널에서 다른 셸(예: KornShell(ksh))에 들어가 시도합니다.$SHELL두 경우 모두 결과가 bash로 표시됩니다.
셸의 현재셸의가사면용려져를 사용합니다.cat /proc/$$/cmdline 셸 는 리고셸파경 로는의입니다.readlink /proc/$$/exe.
셸과 그에 상응하는 버전을 알아내는 방법은 여러 가지가 있습니다.여기 저에게 효과가 있었던 몇 가지가 있습니다.
직설적인
- $> echo $0 (프로그램 이름을 제공합니다.제 경우 출력은 -bash였습니다.)
- $> $SHELL (셸로 이동하고 프롬프트에서 셸 이름과 버전을 얻습니다.나의 경우 bash3.2$).
- $> echo $SHELL (실행 경로가 제공됩니다.내 경우에는 /bin/bash.)
- $> $SHELL --version (라이센스 유형이 있는 셸 소프트웨어에 대한 전체 정보를 제공합니다)
해키시 접근법
$> ******* (랜덤 문자 집합을 입력하면 출력에 셸 이름이 표시됩니다.내 경우 -bash: chapter2-a-sample-isomorphic-app: 명령을 찾을 수 없음)
현재 껍질을 찾는 간단한 방법이 있습니다.명령이 아닌 임의 문자열을 입력하기만 하면 됩니다.실패하고 "찾을 수 없음" 오류가 반환되지만 줄의 시작 부분에서 다음과 같이 표시됩니다.
ksh: aaaaa: not found [No such file or directory]
bash: aaaaa: command not found
ps는 가장 신뢰할 수 있는 방법입니다.SHELL 환경 변수는 설정이 보장되지 않으며 설정이 되어 있더라도 쉽게 스푸핑할 수 있습니다.
저는 다양한 접근 방식을 시도해 보았는데, 저에게 가장 적합한 접근 방식은 다음과 같습니다.
ps -p $$
또한 Cygwin에서 작동하며 PID 그리핑과 같은 잘못된 긍정을 생성할 수 없습니다.일부 클리닝을 사용하면 실행 파일 이름(경로가 있는 Cygwin 아래)만 출력됩니다.
ps -p $$ | tail -1 | awk '{print $NF}'
함수를 생성하여 외울 필요가 없습니다.
# Print currently active shell
shell () {
ps -p $$ | tail -1 | awk '{print $NF}'
}
나서 그냥 ...그런 다음 그냥 실행합니다.shell.
Debian과 Cygwin에 의해 테스트되었습니다.
사용된 합니다. 셸 셸 이름)이.ksh93에 ksh등).위해서/bin/sh 사용된, 그은실사껍보질여것줄입다즉니을용된제.dash.
ls -l /proc/$$/exe | sed 's%.*/%%'
저는 많은 사람들이 다음과 같이 말하는 것을 알고 있습니다.ls출력을 절대 처리해서는 안 됩니다. 하지만 특수 문자로 이름이 지정되거나 특수 문자로 이름이 지정된 디렉토리에 배치된 셸을 사용할 확률은 얼마나 됩니까?만약 이것이 여전히 사실이라면, 그것을 다르게 하는 많은 다른 예들이 있습니다.
Toby Speight가 지적한 바와 같이, 이는 동일한 목표를 달성하는 보다 적절하고 깨끗한 방법일 것입니다.
basename $(readlink /proc/$$/exe)
상위 프로세스 인쇄에 대한 나의 변형:
ps -p $$ | awk '$1 == PP {print $4}' PP=$$
AWK가 해줄 수 있을 때 불필요한 애플리케이션을 실행하지 마세요.
의 만약당이신이 제공되는 /bin/sh에는 POSIX 표준이 .lsof -된 - 한대안가의 한 대안lsof에는 이경에는일 수 .pid2path전체 경로를 인쇄하는 다음 스크립트를 사용하거나 조정할 수도 있습니다.
#!/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}'
내 솔루션:
ps -o command | grep -v -e "\<ps\>" -e grep -e tail | tail -1
이것은 다양한 플랫폼과 셸을 통해 이동할 수 있어야 합니다.그것은 사용합니다.ps다른 솔루션과 마찬가지로, 그러나 그것은 의존하지 않습니다.sed또는awk 배관 및▁from▁and,▁piping고걸▁and▁out▁filters,ps셸이 항상 마지막 항목이어야 합니다.이렇게 하면 휴대용이 아닌 PID 변수에 의존하거나 올바른 선과 열을 선택할 필요가 없습니다.
저는 Bash, Z shell로 데비안과 macOS를 테스트했습니다.zsh) 및 fish(다른 PID 변수를 사용하기 때문에 fish에 대한 식을 변경하지 않고는 대부분의 솔루션에서 작동하지 않습니다.
(특정 Bash를 실행 하려면 (으)로 실행 중인 Bash를 하는 .$BASH_VERSINFO배열 변수입니다.(읽기 전용) 어레이 변수로는 환경에서 설정할 수 없으므로 현재 셸에서 가져온 것인지 확인할 수 있습니다.
는 "Bash"로 때"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 버전이 호환될 것이라고 가정할 수 있습니다.
셸에서 작동하는 답변이 없습니다(변수가 없습니다).$$또는$0).
이것은 나에게 효과가 있습니다(테스트 완료).sh,bash,fish,ksh,csh,true,tcsh,그리고.zshopenSUSE 13.2):
ps | tail -n 4 | sed -E '2,$d;s/.* (.*)/\1/'
는 이명령문자같출력니다합과 같은 합니다.bash여기서만 사용합니다.ps,tail,그리고.sed, (GNU 확자없음시; 추도가장)도) 추가 )--posix명령입니다.모두 표준 POSIX 명령입니다.확실합니다.tail수 , 내 제할수있만지나, 의거의.sedfu는 이것을 하기에 충분히 강하지 않습니다.
제가 보기에 이 솔루션은 OS X에서 작동하지 않기 때문에 휴대성이 높지 않은 것 같습니다. :(
echo $$ # Gives the Parent Process ID
ps -ef | grep $$ | awk '{print $8}' # Use the PID to see what the process is.
당신은 어떻게 당신의 현재 껍질이 무엇인지 알 수 있습니까?
이것은 그다지 깨끗한 해결책은 아니지만, 여러분이 원하는 것을 해줍니다.
# 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)에서만 작동합니다.
셸에서 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로 (을로변 Bash경셸))
참고: 위 명령에서 /bin/sh가 이미 존재한다는 오류가 발생하면 /bin/sh를 제거하고 다시 시도하십시오.
저는 Nahuel Fouilule의 솔루션을 특히 좋아하지만, Bash 쉘이 내장된 Ubuntu 18.04(바이오닉 비버)에서 다음과 같은 버전의 솔루션을 실행해야 했습니다.
bash -c 'shellPID=$$; ps -ocomm= -q $shellPID'
변수 시 변 없 음수임 shellPID예: 다음과 같습니다.
bash -c 'ps -ocomm= -q $$'
출력만 하면 됩니다.ps를 다 것은 도 있고 .여러분 모두가 비 대화형 모드를 사용하지는 않을 수도 있습니다. 그리고 그것이 차이를 만듭니다.
구입께와 하십시오.$SHELL환경 변수입니다.간단한 sed로 경로를 제거할 수 있습니다.
echo $SHELL | sed -E 's/^.*\/([aA-zZ]+$)/\1/g'
출력:
bash
macOS, Ubuntu 및 CentOS에서 테스트되었습니다.
Mac OS X(및 FreeB)에서SD):
ps -p $$ -axco command | sed -n '$p'
/proc 디렉터리 구조에서 PID에 대한 해당 명령줄을 읽을 수 있으므로 "ps"의 출력에서 PID를 가져올 필요가 없습니다.
echo $(cat /proc/$$/cmdline)
그러나 이는 단순히 다음과 같은 것보다 나을 수 없습니다.
echo $0
이름이 나타내는 것과 실제로는 다른 셸을 실행하는 경우 이전에 얻은 이름을 사용하여 셸에서 버전을 요청하는 것이 한 가지 방법이 있습니다.
<some_shell> --version
sh다른 사용자들이 유용한 것을 제공하는 동안 종료 코드 2에서 실패하는 것 같습니다(그러나 나는 그것들이 없기 때문에 모든 것을 확인할 수 없습니다).
$ sh --version
sh: 0: Illegal option --
echo $?
2
한 가지 방법은:
ps -p $$ -o exe=
를 사용하는 가 더 .-o args또는-o comm다른 대답에서 제안된 것처럼 (이것들은 예를 들어, 언제와 같은 어떤 상징적인 링크를 사용할지도 모릅니다./bin/sh일부 특정 셸(Dash 또는 Bash)을 가리킵니다.
하지만 /인해 경로 /usr-merge)를 해야 할 수 ./bin/bash 그리고. /usr/bin/bash).
또한 상기 내용은 POSIX와 완전히 호환되지 않습니다(POSIX ps에는exe).
이 유용한 명령을 사용해 보십시오.
echo $SHELL
다음 명령을 사용하십시오.
ps -p $$ | tail -1 | awk '{print $4}'
이것은 RHEL(Red Hat Linux), macOS, BSD 및 일부 AIX에서 잘 작동합니다.
ps -T $$ | awk 'NR==2{print $NF}'
또는 pstree를 사용할 수 있는 경우 다음과 같은 것도 작동해야 합니다.
pstree | egrep $$ | awk 'NR==2{print $NF}'
사용할 수 있습니다.echo $SHELL|sed "s/\/bin\///g"
제가 생각해낸 것은 다음과 같습니다.
sed 's/.*SHELL=//; s/[[:upper:]].*//' /proc/$$/environ
언급URL : https://stackoverflow.com/questions/3327013/how-to-determine-the-current-interactive-shell-that-im-in-command-line
'programing' 카테고리의 다른 글
| 각도 2 - 내부HTML 스타일 (0) | 2023.05.29 |
|---|---|
| RabbitMQ / AMQP: 동일한 메시지에 대해 단일 대기열, 다중 소비자? (0) | 2023.05.29 |
| iOS 10에서 Xcode 7 사용 (0) | 2023.05.29 |
| 버튼 클릭 시 비동기 메서드 호출 (0) | 2023.05.29 |
| 현재 날짜를 열의 기본값으로 사용 (0) | 2023.05.09 |