exit
터미널에서 나가지 않도록 내장 기능을 대체하는 함수를 작성하려고합니다 .
SHLVL
환경 변수 를 사용하려고 시도했지만 하위 쉘 내에서 변경되지 않는 것 같습니다.
$ echo $SHLVL
1
$ ( echo $SHLVL )
1
$ bash -c 'echo $SHLVL'
2
내 기능은 다음과 같습니다.
exit () {
if [[ $SHLVL -eq 1 ]]; then
printf '%s\n' "Nice try!" >&2
else
command exit
fi
}
exit
그래도 하위 쉘 내 에서 사용할 수는 없습니다 .
$ exit
Nice try!
$ (exit)
Nice try!
서브 쉘에 있는지 여부를 감지하는 좋은 방법은 무엇입니까?
답변
bash에서는 다음과 비교할 $BASHPID
수 있습니다.$$
$ ( if [ "$$" -eq "$BASHPID" ]; then echo not subshell; else echo subshell; fi )
subshell
$ if [ "$$" -eq "$BASHPID" ]; then echo not subshell; else echo subshell; fi
not subshell
배쉬가 아닌 경우 $$
, 서브 쉘에서 동일하게 유지되어야하므로 실제 프로세스 ID를 얻는 다른 방법이 필요합니다.
실제 pid를 얻는 한 가지 방법은 sh -c 'echo $PPID'
입니다. ( … )
껍질을 평평 하게 넣으면 껍질이 포크를 최적화하여 작동하지 않는 것처럼 보일 수 있습니다. ( : ; sh -c 'echo $PPID'; : )
서브 쉘이 너무 복잡하여 최적화 할 수 없다고 생각되도록 추가 no-op 명령 을 시도하십시오 . 이 접근법에 대한 크레딧은 스택 오버플 로에서 John1024 에게 전달됩니다 .
답변
어때요 BASH_SUBSHELL
?
BASH_SUBSHELL
쉘
이 해당 환경에서 실행을 시작할 때 각 서브 쉘 또는 서브 쉘 환경 내에서 하나씩 증가 합니다. 초기 값은 0입니다.
$ echo $BASH_SUBSHELL
0
$ (echo $BASH_SUBSHELL)
1
답변
[이것은 의견 이었음에 틀림 없다. 그러나 나의 의견은 중재자에 의해 삭제되는 경향이 있으므로, 삭제 된 경우에도이를 참조로 사용할 수있는 답변으로 유지 될 것이다]
사용은 BASH_SUBSHELL
그것이 단지 1로 설정할 수로 완전히 신뢰할 수없는 몇 가지 모든 서브 쉘에서, 서브 쉘.
$ (echo $BASH_SUBSHELL)
1
$ echo $BASH_SUBSHELL | cat
0
파이프 라인 명령이 실행되는 하위 프로세스가 아니라고 주장하기 전에 정말 실제 서브 쉘이이 고려 man bash
조각을 :
파이프 라인의 각 명령은 별도의 프로세스 (즉, 서브 쉘)로 실행됩니다.
그리고 실질적인 의미-스크립트 조각이 일부 프로세스 퀴즈가 아닌 하위 프로세스에서 실행되는지의 여부입니다.
이 질문 에 대한 답변에서 이미 설명한 바와 같이 유일한 해결책 은 $BASHPID
동일 $$
하거나 이식 가능하지만 효율성이 떨어지는 지 확인하는 것입니다.
if [ "$(exec sh -c 'echo "$PPID"')" != "$$" ]; then
echo you\'re in a subshell
fi