~에서https://unix.stackexchange.com/a/276611/674:
bash가 -c로 실행되면 비대화형 쉘로 처리되며 -i를 지정하지 않으면 ~/.bashrc를 읽을 수 없습니다.
비대화형 쉘은 어떻게 정의됩니까?
비대화형 쉘은 stdin의 입력을 받아들일 수 없는 쉘로 정의됩니까? 예를 들어,
bash -c cat
stdin의 입력이 허용될 수 있습니다.비대화형 쉘이 stdout으로 출력할 수 있습니까? 예를 들어,
bash -c date
표준 출력에 쓸 수 있습니다.
bash -c
(추가 옵션 없음)-i
항상 비대화형 쉘을 생성하시겠습니까?
답변1
나는 약간의 연구를했다. Bash 소스 코드에 따르면.
긴 이야기 짧게
비대화형 쉘은 어떻게 정의됩니까?
- 누락된 명령 기록
- 업무에는 지원되지 않습니다.
- 라인 편집 기능 없음
- 줄 번호를 가져오는 중 오류가 발생했습니다.
- 프롬프트 없음
- 첫 번째 오류 후 실행 중지
bash -c(추가 -i 옵션 없이)는 항상 비대화형 쉘을 생성합니까?
예
더 긴 버전.
이 함수는 bash가 옵션을 수신할 때 호출됩니다 -c
.
no_line_editing = 1
즉, 백스페이스 키를 사용하여 명령을 편집할 수 없습니다.
bash_history_reinit (0);
기록 및 명령 자동 완성을 비활성화합니다.
static void
init_noninteractive ()
{
#if defined (HISTORY)
bash_history_reinit (0);
#endif /* HISTORY */
interactive_shell = startup_state = interactive = 0;
expand_aliases = posixly_correct; /* XXX - was 0 not posixly_correct */
no_line_editing = 1;
#if defined (JOB_CONTROL)
/* Even if the shell is not interactive, enable job control if the -i or
-m option is supplied at startup. */
set_job_control (forced_interactive||jobs_m_flag);
#endif /* JOB_CONTROL */
}
강제로 실행하지 않는 한 작업 제어는 기본적으로 비활성화됩니다.-m
/* We can only have job control if we are interactive unless we
force it. */
if (interactive == 0 && force == 0)
{
job_control = 0;
original_pgrp = NO_PID;
shell_tty = fileno (stderr);
}
구문 오류 메시지에는 줄 번호가 포함됩니다.
/* Report a syntax error with line numbers, etc.
Call here for recoverable errors. If you have a message to print,
then place it in MESSAGE, otherwise pass NULL and this will figure
out an appropriate message for you. */
static void
report_syntax_error (message)
char *message;
{
...
if (interactive == 0)
print_offending_line ();
...
}
간단한 테스트
root@test:~# ;;
-bash: syntax error near unexpected token `;;'
root@test:~# bash -c ';;'
bash: -c: line 0: syntax error near unexpected token `;;'
bash: -c: line 0: `;;'
명령이 실행된 후에는 프롬프트가 인쇄되지 않습니다.
/* Issue a prompt, or prepare to issue a prompt when the next character
is read. */
static void
prompt_again ()
{
char *temp_prompt;
if (interactive == 0 || expanding_alias ()) /* XXX */
return;
첫 번째 오류 후에 명령 실행이 중지됩니다.
/* Parse error, maybe discard rest of stream if not interactive. */
if (interactive == 0)
EOF_Reached = EOF;
답변2
셸 세션에는 다음과 같은 다양한 옵션이 있습니다.
- 별칭이 확장되었는지 여부
- 누군가/무엇이 STDIN에 입력 중입니다.
- 시스템이 로드되었는지 여부를 완료하세요.
- 명령이 기록 파일에 저장된 경우
- 쉘이 시작될 때 어떤 파일을 얻습니까?
대화형 셸은 이러한 특성 중 일부를 갖는 셸입니다. 그러나 원하는 대로 이러한 옵션을 켜거나 끌 수 있습니다. 이 용어를 interactive shell
우리가 일반적으로 이해하는 쉘 상호 작용에 필요한 동작 모음 으로 생각하십시오 .
부트 셸을 사용할 때 일반적으로 시스템에 문제가 있음을 나타내기 때문에 -i
약간 혼란스러울 수 있습니다 . 이러한 셸 옵션 중 일부는 사람들이 일반적으로 대화형 셸로 이해하는 것과 다른 값을 가질 수 있습니다.
따라서 구체적으로 귀하의 예 bash -c cat
는 완료를 활성화하지 않으며 기록에 아무것도 저장하지 않습니다. 나는 그것을 그렇게 부르고 싶지 않지만 interactive
원한다면 그렇게 할 수 있습니다.
답변3
대화형 쉘은 stdin에서 명령을 읽는 쉘로 정의됩니다.
비대화형 쉘이 대화형으로 "define" 옵션을 사용하여 파일( )을 -i
읽는지는 정의되지 않습니다.$ENV
~/.*rc