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

関連情報