対話型シェルが非対話型シェルになり、その逆も可能ですか?
メモ:「インタラクティブと非インタラクティブの違いは何ですか?」という基本的な質問について多くの研究を行い、研究結果に基づいて次のような質問をしました。これ質問。
この質問は部分的に重要なので、序文は長いです。タイプこの質問に答えるために、私たちは「相互作用」の定義を使います。定義はコレクションのすべてのラベルにすることができ、さまざまな属性を記述することもできます。行動を予測するそして理解する目的。 「アクション定義」または「動的定義」と呼ばれる最後のタイプが最も便利です。
では、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番目の文は、次のように使用される条件を定義します。煙「対話型」として定義された特定のモードでシェルが起動するかどうかを決定します。
気づくはいいいえこの文を次のように解釈してください。 " $-
bashシェルは 'i'が含まれている場合にのみインタラクティブです。" $-
代わりに便利な指標のようです。定義相互作用の。これは私の質問にとって非常に重要です。
両方(POSIXsh
定義とBash定義)は、「対話型」ラベルが実行されているシェルに適用される状況を示す機械的定義です。彼らはそうではありませんアクション定義何もしないから影響このラベルの。
しかし、私はBashのマニュアルページの残りの部分が「対話型シェルでない限り」または「対話型シェルでのみ、または_____オプションが設定されていない場合」、特定の方法で動作するシェルへの参照でいっぱいであることを発見しました。 (例が多すぎてこの質問のポイントではありません。)
したがって、私は、「対話型」がマニュアルページの残りの部分で説明されている基本的な「対話型」動作(オプション設定)のコレクションのための便利なラベルにすぎないことを認めます。それ自体は基本的な用語や目的ではなく、基本的な概念です。シェルのソースコード以外には権限のある定義はありません。 (カーネル独自の設計に組み込まれた抽象化を表す「ファイル記述子を開く」や「プロセスを停止する」などの用語とは異なります。)
(POSIX定義にも定義されていますが、「シェルがインタラクティブでない場合」と同様の説明は、sh
マニュアルページ[]ではるかに少ない頻度で使用され、ほぼ完全に呼び出し時間の違いに焦点を当てています。今)。man 1p sh
man bash
シェル「インタラクティブ」のいくつかの意味は関連しています。電話するときとにかく、たとえば他のコマンドを読み取る前にシェルが取得するファイル。しかしはい(少なくともBashでは)常に関係があるという意味です。したがって、特定の状況に応じて決定する方法が必要です。走るインタラクティブかどうかはシェルです。
インタラクティブBashシェルで実行すると、set +i
「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.
正確な定義を厳密に読むと、次のような質問が提起されます。対話型端末のstdinまたはstderrがリダイレクトされて端末に接続されなくなった場合、シェルは非対話型になりますか?
(それ現れるこの質問に対する答えは「いいえ」です。マニュアルページには、「標準入力とエラーの両方が端末に接続されています...」という修飾子を含めることができます。電話するとき、「でもよく分からない。)
答えが「いいえ、シェルは非対話型にすることはできず、その逆も同様です」何ですか明確なシェルがインタラクティブであるかどうかを確認するには?
言い換えれば:その後も「対話型シェル」の動作が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
これにより、「interactive」と「has」i
の値を確認します。$-
いいえ同じ。
${parameter:?word}
パラメータセットを使用しない同様のテストは同様の結果を生成し、これがシェル相互作用の$-
「真実のソース」ではないことを再確認します。
だからついに、シェルの明示的な「相互作用」機能はどこに保存されますか?
そして、対話型シェルが非対話型シェルになり、その逆も可能ですか? (…この機能を変更したら?)
答え1
私がしたい質問はなぜ誰かがこれをしたいのですか?
次の対話型シェルの特定の側面を無効にできます。
PS1= PS2=
プロンプトを無効にするset +m
ジョブ制御の無効化- 一部のシェルで履歴を無効にする
zle
からおよびすべての完成モジュールを削除することもできますzsh
。
ただし、シェルの対話を停止するには、次の手順を実行できます。
. /some/file; exit
残りのコマンドをインポートするように指示します(/some/file
ttyデバイスからコマンドを読み続けるには、に置き換えます)。しかし、動作やまだ実行するという事実のように、非対話型シェルとはまだいくつかの違いがあります。ジョブ制御または:/dev/tty
return
exec myshell /dev/tty
現在の対話型シェルを、ttyデバイスからコマンドを読み続ける非対話型シェルに置き換えます。
bash 4.4では、set +i
返された結果はbash: set: +i: invalid option
他のほとんどのシェルの結果と似ています。