쉘이 로그인 / 인터랙티브 / 배치인지 확인하는 방법


143

대화 형, 로그인 및 배치 셸의 차이점을 이해한다고 생각합니다. 자세한 도움말은 다음 링크를 참조하십시오.

내 질문은 대화 형, 로그인 또는 배치 쉘에있는 경우 명령 / 조건으로 어떻게 테스트 할 수 있습니까?

명령 또는 조건 ( true또는 반환 false)을 찾고 있으며 if 문에 배치 할 수도 있습니다. 예를 들면 다음과 같습니다.

if [[ condition ]]
   echo "This is a login shell"
fi

3
또 다른 질문이 있습니다. STDIN 및 / 또는 STDOUT이 tty (터미널) 또는 파이프 (파일 또는 프로세스)에 연결되어 있습니까? 이것은 아래 주석 중 일부에 설명 된대로 관련이 있지만 고유 한 테스트입니다.
Mark Hudson

답변:


160

bash태그에 쉘이 나열되어 있지 않으므로 쉘 또는 이와 유사한 것으로 가정 합니다.

대화식 쉘에 있는지 확인하려면 다음을 수행하십시오.

[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'

로그인 쉘에 있는지 확인하려면 다음을 수행하십시오.

shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'

"일괄 처리"라는 말은 "대화식이 아님"을 의미한다고 가정하므로 대화식 쉘을 검사하면 충분합니다.


12
의 경우 zsh: 사용자 로그인 쉘에 대한 검사를 수행 할 수 있습니다if [[ -o login ]] ...
CHB

1
"사용자"가 "cron"대 프로그램을 실행했는지 알고 싶다면 [[TERM == "dumb"]] && echo "cron에서 실행
Erik Aronesty

10
@ErikAronesty 모든 바보 터미널이 크론 세션은 아닙니다.
Chris Down

2
“태그에 셸이 없기 때문에 bash 쉘 또는 이와 유사한 것으로 가정합니다.”–이 문장의 논리는 정말 아름답습니다! :)
Michael Le Barbier Grünewald

2
@antonio 그것은 당신의 인용이 잘못되어 $-현재 쉘에서 확장되고 있기 때문 입니다. 전체 표현식에 작은 따옴표를 사용하면 올바른 결과를 얻을 수 있습니다.bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'
Chris Down

33

Bourne 스타일 쉘에서 i옵션은 쉘이 대화식인지 여부를 나타냅니다.

case $- in
  *i*) echo "This shell is interactive";;
  *) echo "This is a script";;
esac

로그인 쉘을 테스트하기위한 이식 가능하고 신뢰할 수있는 방법은 없습니다. Ksh 및 zsh가에 추가 l됩니다 $-. Bash는으로 login_shell쿼리 할 수 있는 옵션을 설정합니다 shopt -q login_shell. 이식 가능하게 : : 쉘로 $0시작 하는지 여부를 테스트 -하면 호출자 -가 인수 0에 접두사를 추가했기 때문에 일반적으로 로그인 쉘인지 알 수 있습니다 (일반적으로 실행 파일의 이름 또는 경로). 로그인 쉘을 호출하는 쉘 특정 방법 (예 :)을 감지하지 못합니다 ash -l.


(...) 발신자 때문에 –이 조각에 빠진 것이 있다고 생각합니다.
Piotr Dobrogost

$0시작 -방법에 관계없이 항상 시작하는 것이 이상적입니다 . 그러나 적어도 하나의 예외가 있습니다 : 이것은 로그인 쉘이어야한다고 해도 bash에 항상 해당되는 것은 아닙니다 . 상자에서 사용해보십시오 : invoke bash --login, $0여전히 읽습니다 bash.
Wirawan Purwanto

@WirawanPurwanto 나는 당신의 의견을 이해하지 못합니다. 내가 마지막 문장에 쓴 것이 아닌가?
Gilles

@Gilles : 맞습니다. 마지막 문장을 놓 쳤어요.
Wirawan Purwanto

24

생선 껍질

fish다른 사용자가이 페이지를 우연히 발견 한 경우에 대한 답변입니다 .

if status --is-interactive
    # ...
end

if status --is-login
    # ...
end

echo "darn, I really wanted to have to use globs or at least a case statement"

생선 문서 : 초기화


1
불필요한 편집을 위해 -1입니다.
Nick Bastin

6
@NickBastin의 의견을 궁금해하는 사람은 공정한 지적을 받았으므로 편집했습니다. 원래의 양도는 이제 절반으로 줄었습니다.
ohspite

18

csh / tcsh

들어 cshtcsh나는 내에서 다음 한 .cshrc파일 :

if($?prompt) then               # Only interactive shells set $prompt
    ...
endif

특히 tcsh, 변수 loginsh는 로그인 쉘에 대해 설정됩니다.

if($?loginsh) then              # A login shell..
    ...
endif

( tcsh또한 shlvl로그인 쉘의 값이 1 인 중첩 쉘의 수로 설정 되는 변수 가 있습니다.)


2
PS1대화식 쉘을 테스트하기 위해 작동하지 않습니다. 거의 항상 대화 형으로 설정되어 있지만 설정을 해제 할 수 있습니다. 많은 시스템이에 포함 export PS되어 있기 때문에 비 대화식 쉘로 설정되는 경우가 많습니다 /etc/profile.
Gilles

@Gilles 수정 및 편집 해 주셔서 감사합니다
Andrew Stein

17

다른 방법은 결과를 확인하는 것입니다 tty

if [ "`tty`" != "not a tty" ]; then

10
... 또는 [ -t 0 ]STDIN이 tty인지 테스트 하는 데 사용 합니다. 필요에 따라 1 (STDOUT) 또는 2 (STDERR)를 사용할 수도 있습니다.
derobert

@derobert-새로운 것을 보여 주셔서 감사합니다
Adrian Cornish

10
이것은 다른 테스트입니다. 터미널에서 스크립트를 실행할 때마다 입력이 터미널 인 비 대화식 쉘을 가질 수 있으며 터미널에서 입력을받지 않는 대화식 쉘을 가질 수 있습니다 (드물지만).
Gilles

@Gilles 쉘이 인터랙티브하고 아이와 disown살아남은 채로 닫히면 tty더 이상 인터랙티브하지 않다는 것을 알기 위해 최선을 다 $-했지만 변경되지 않았습니다. 나는 여전히 최선의 접근 방식에 대해 의아해합니다.
물병 자리 힘

5
@AquariusPower 그런 다음 테스트하려는 것은 대화식 쉘이 아니라 표준 입력이 터미널인지 여부입니다. 사용하십시오 [ -t 0 ]. PS 이전의 의견에서, 나는“강한 상관 관계가있다”는 글을 썼습니다.“ #!/bin/sh비대화 형이지만 터미널에 연결할 수있는“ 일반적으로 시작되는 스크립트 등 은 예외입니다.”
Gilles

8

UNIX / Linux에는 터미널이 있는지 확인하는 명령이 있습니다.

if tty -s
then
echo Terminal
else
echo Not on a terminal
fi

1
이것은 dash또한 작동합니다 .
Ken Sharp

7

stdin이 터미널인지 확인할 수 있습니다.

if [ -t 0 ]
then
    echo "Hit enter"
    read ans
fi

3

스크립트가 대화식 또는 비 대화식 쉘에서 실행되는지 확인하기 위해 $PS1변수에 저장된 프롬프트가 있는지 스크립트를 확인 합니다.

if [ -z $PS1 ] # no prompt?
### if [ -v PS1 ]   # On Bash 4.2+ ...
then
  # non-interactive
  ...
else
  # interactive
  ...
fi

이것은 여기에서 배웠습니다 : https://www.tldp.org/LDP/abs/html/intandnonint.html


1

i찾는 올바른 옵션이 아닙니다. -i비 대화식 쉘이 대화식이되도록 강제하는 것입니다. 올바른 자동 활성화 옵션은 -s이지만 Bash는 불행히도 이것을 올바르게 처리하지 못합니다.

$-포함 여부 s(자동 활성화가 허용되는지) 또는 포함 여부 i(자동 활성화가 허용되지는 않지만 공식적으로 -i쉘 의 명령 행 옵션 에만 연결됨)를 확인해야합니다 .


1
s쉘이 대화식인지 여부가 아니라 stdin에서 명령을 읽는 경우입니다. 대화식 쉘은 반드시 stdin에서 명령을 읽을 필요는 없습니다 ( zsh -i < /dev/nullzsh는 예외입니다). 그리고 쉘은 stdin에서 명령을 읽고 대화 형이 아니 sh < file거나 (와 같은 echo 'echo "$1"' | sh -s foo bar) 수 있습니다.
Stéphane Chazelas

2
내가 지적하고자하는 것은 원래 Bourne Shell이 ​​대화 형으로 의도 된 경우에도 $-에 'i'가 없다는 것입니다.
schily

그러나 U & L에서 "쉘"은 현대 쉘 을 나타내는 경향이 있습니다. Bourne 쉘은 일반적으로 유물로 간주되며 자신의 변형은 명시 적으로 명시하지 않는 한 사람들이 당신이 말하는 것을 알기를 기대할 정도로 주류가 아닙니다. 언급 [[...]]된 질문은 ksh / bash / zsh를 의미합니다. 당신은 같은 지점있어 역사 노트 를 확인하는 것을 i에서하는 $-Bourne 쉘에서 작동하지 않습니다를. 그러나 확인 s이 제대로 작동하지 않습니다. 당신은 또한 확인 싶어 [ -t 0 ]하거나 i; 심지어 다음과 같은 모퉁이 사건에 속을 것입니다echo 'exec < /dev/tty; that-check' | sh'
Stéphane Chazelas

Solaris 10까지의 Solaris는 원래 Bourne Shell과 함께 제공되며 씰에는 에이프 록스가 포함되어 있습니다. SVr4 이후 셸에있는 것으로 알려진 10 가지 버그. 따라서 Bourne Shell에 힌트를 추가하는 것은 당신이 살아있을 수있는만큼 모자가 아닙니다. 다른 쪽의 zsh는 호환성이 충분하지 않습니다. 예를 들어 zsh와 함께 "configure"를 실행하려고하면 실패하므로 / bin / sh를 zsh를 가리 키도록 설정해야합니다. BTW : Bourne Shell은 대화식으로 결정되는 경우 기본적으로 -i를 설정합니다.
schily

3
POSIX가 $-contains i (s가 필요한 것 같습니다)를 요구하지 않는 것 같습니다. austin-group ML에 대한 질문을 제기 할 것입니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.