対話型シェルは非対話型になりますか?
注:「対話型と非対話型の違いは何ですか?」という基本的な質問について多くの研究を行ってきましたが、研究の結果、この質問をすることになりました。
この質問には、回答するために「インタラクティブ」にどのタイプの定義を使用するかが重要であるため、部分的に長い前文があります。定義は、特定のセットの任意のラベルです。さまざまなプロパティを説明できます。または、行動を予測し、目的を理解するために使用できる情報を提供できます。 この最後のタイプは、「アクション定義」または「動的定義」と呼ぶことができ、最も便利です。
ではman 1p sh
、対話型シェルの次の定義が提供されています。
If the -i option is present, or if there are no operands and the shell’s standard input and standard error are attached to a terminal, the shell is considered to be interactive.
「-iオプション」の記述と「オペランド」という言葉の使用から、これは実行中のシェルで調べることができる属性ではなく、シェルの呼び出しを指します。
Bashのマニュアルページでは、少し異なる表現をしています。
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.
最初の文の定義は、シェルの開始のみを参照しています。
2番目の文(私の読書では)は、「対話型」として定義されている特定の方法でシェルが開始されたかどうかを確立するためのプロキシとして使用される条件を定義します。
この文は、「 'i'が含まれている場合にのみ、bashシェルはインタラクティブです」と解釈していない$-
ことに注意してください。$-
単なる便利なインジケータであり、インタラクティブの定義ではないようです。これは私の質問に非常に重要です。
これらの両方(POSIX sh
定義とBashの定義)は、起動したシェルに「対話型」というラベルがどのような状況で適用されるかを示す機械的な定義です。これらはこのラベルの意味を与えないので、アクションの定義ではありません。
ただし、Bashのマニュアルページの残りの部分では、「対話型シェルでない限り」または「対話型シェルでのみ、または_____オプションが設定されている場合」特定の方法で動作するシェルへの参照が散在しています。(多数の例がありますが、それがこの質問の要点ではありません。)
したがって、「対話型」は、残りのマニュアルページ全体で説明されているデフォルトの「対話型」動作(オプション設定)のコレクションの単なる便利なラベルであることを受け入れます。それ自体は基本的な用語やオブジェクトではありません。シェルのソースコード以外には信頼できる定義はありません。(たとえば、カーネル自体の設計に組み込まれた抽象化を指す「ファイル記述子を開く」または「プロセスを停止」という用語とは異なります。)
(POSIXの定義でも定義されていますがsh
、manページ[ man 1p sh
]は「シェルが対話的でない限り」および類似のステートメントの使用がはるかに少なくman bash
、呼び出し時間の違いにほぼ専念しているため、Bashに焦点を当てますこの時点以降。)
シェルが「対話式」であるという意味のいくつかは、いずれにせよ、起動時にのみ関連します。たとえば、シェルが他のコマンドを読み取る前にどのファイルをソースとするかなどです。ただし、(少なくともBashでは)いつでも関連する影響があります。したがって、任意の実行中のシェルに対して、対話型かどうかを判断する方法が必要です。
set +i
対話型のBashシェルで実行すると、のコンテンツから「i」が削除され$-
ます。
問題は、これは実際にシェルがもはや対話的ではなくなったことを意味しますか?
Bashの正確な定義では、定義のどこにも「i」が存在する必要はないため、そうすべきではありません:$-
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option.
厳密な定義を厳密に読み取ると、疑問が生じます。対話型端末のstdinまたはstderrがリダイレクトされ、端末に接続されなくなった場合、シェルは非対話型になりますか?
(表示され、「その標準入力と標準エラーの両方...端子に接続されています。この1への答えが「NO」とmanページが修飾含まれていない可能性があることを、呼び出し時に」私は知りません間違いなく。)
答えが「いいえ、シェルが非対話型にならない、またはその逆はできない」場合、シェルが対話型かどうかを決定する決定的な方法は何ですか?
さらに別の言い方をすると、「対話型シェル」の動作が後set +i
に持続する場合、それらの動作が引き続き適用されるべきであると判断するために何が使用されますか?
ないように誰もがそれを疑う:ありますシェルの振る舞いは後も持続され、対話的に呼び出さset +i
とシェルの行動が後も持続た非対話的に呼び出されますset -i
。例として、次の抜粋を検討してman bash
ください。
COMMENTS In a non-interactive shell, or an interactive shell in which the inter- active_comments option to the shopt builtin is enabled (see SHELL BUILTIN COMMANDS below), a word beginning with # causes that word and all remaining characters on that line to be ignored. An interactive shell without the interactive_comments option enabled does not allow comments. The interactive_comments option is on by default in interac- tive shells.
したがって、interactive_comments
オプションの設定を解除すると、インタラクティブシェルと非インタラクティブシェルの違いがわかります。この違いの持続性は、次のスクリプトによって示されます。
#!/bin/bash
# When the testfile is run interactively,
# all three comments will produce an error
# (even the third where 'i' is not in '$-').
# When run noninteractively, NO comment will
# produce an error, though the second comment
# is run while 'i' IS in '$-'.
cat >testfile <<'EOF'
shopt interactive_comments
shopt -u interactive_comments
shopt interactive_comments
echo $-
#first test comment
set -i
echo $-
#second test comment
set +i
echo $-
#third test comment
EOF
echo 'running bash -i <testfile'
bash -i <testfile
echo 'running bash <testfile'
bash <testfile
これにより、「対話型」と「i
の値にある$-
」は同等ではないことが確認されます。
${parameter:?word}
パラメータを設定せずに使用した同様のテストでは、同様の結果が得られ、$-
シェルの対話性の「真実の源」ではないことが確認されました。
それで、最後に、シェルの決定的な「対話性」特性はどこに保存されていますか?
また、インタラクティブシェルが非インタラクティブになったり、その逆になることはありますか? (...この特性を変更することにより?)