bash -c 및 비대화형 쉘

bash -c 및 비대화형 쉘

~에서https://unix.stackexchange.com/a/276611/674:

bash가 -c로 실행되면 비대화형 쉘로 처리되며 -i를 지정하지 않으면 ~/.bashrc를 읽을 수 없습니다.

  1. 비대화형 쉘은 어떻게 정의됩니까?

    • 비대화형 쉘은 stdin의 입력을 받아들일 수 없는 쉘로 정의됩니까? 예를 들어, bash -c catstdin의 입력이 허용될 수 있습니다.

    • 비대화형 쉘이 stdout으로 출력할 수 있습니까? 예를 들어, bash -c date표준 출력에 쓸 수 있습니다.

  2. 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

관련 정보