
$-
インクルードを使用できることを知っています私$PS1
シェルがインタラクティブであるかどうかを判断するために、ヌルをチェックまたはチェックします。
しかし、これらのソリューションは現在シェルでのみ機能します。
インタラクティブな直接親シェルを見つけるためのbashスクリプトがあります。
たとえば、
- 対話型シェル:zsh
- bashスクリプト1 bashスクリプト2の実行
- bashスクリプト2には、リアルタイムの対話型シェルを見つけるメカニズムが含まれています。
したがって、対話型シェルでbashスクリプト1を実行すると、zsh
出力はzsh
。
スクリプトがサブシェルで実行されたときにこれを行う方法がわかりません。
ノート
スクリプトを実行するのではなく、実行したいです。
言う
最初の対話型祖先シェルを見つけるためのbashスクリプトがあります。
最初の祖先とは、ボトムアッププロセスチェーンスキャン中に出会った最初の対話型シェルを意味します。
たとえば、次の場合:zsh(最初の対話型シェル) - > bash(2番目の対話型シェル) - > bash(スクリプト1のバッチシェル) - > bash(スクリプト2のバッチシェル)、私たちはbash (2番目の対話型シェル)を出力しようとしています。シェル)。
答え1
これは非常に奇妙な要求です。どのインタラクティブシェルがスクリプトを呼び出すのか、またはインタラクティブシェル以外のプログラムを呼び出してスクリプトを呼び出すのかを気にする必要があるのはなぜですか?これは匂いがとても強いです。XYの問題。
必ず知っておく必要がある場合は、調べようとすることができますが、完全に信頼できる方法はなく、一般的な状況で動作する方法は1つしかないようです。
最初から始めて、探しているプロセスが見つかるまで、または行き過ぎたことを示すプロセスが見つかるまで、スクリプト$PPID
の祖先プロセス()を追跡します。ps -o ppid= -p $ancestor_pid
簡単な戦略は、さまざまなプロセスグループ()でプロセスを見つけることですps -o pgid= -p $ancestor_pid
。通常の状況でスクリプトが対話型シェル(呼び出し側スクリプト)によって呼び出される場合、到達するプロセスはスクリプト(スクリプトの親)を実行するジョブ制御機能を持つシェルです。
この戦略が間違っている可能性があるいくつかの例は次のとおりです。
- チェーンのプロセスの1つが終了しました。
- スクリプトはインタラクティブシェルでは呼び出されず、クローン操作、X11プログラムなどを介して呼び出されます。
lsof
プロセスの標準入力、標準出力、および標準エラー(たとえば、Linuxの外部への移植性が必要ない場合は使用または経由)がスクリプトと同じ端末であることを確認したい場合や望ましくない場合があります。/proc
次の状況をどのように処理するかによって異なります。
bash$ xterm -e your_script
答え2
オプションを確認してください。
[ "$-" = "${-#*i}" ] ||
echo shell is interactive
ファイル記述子を確認することもできます。これは少し違います。シェル自体がインタラクティブであるかどうかは必ずしもわかりませんが、端末と通信しているかどうかはわかります。
for fd in 0 1 2
do [ -t "$fd" ] &&
break
done|| echo shell fds 0 1 2 are not connected to a terminal.
私たちは少しハッキングすることで、端末のすべての用途を把握しようとすることができます。
tty_users()
for fd in 0 1 2 "$@"
do [ -t "$fd" ] && {
fuser "$(tty)"
break; } <&"$fd"
done
現在シェルで実行され、最初に検出された端末で実行されているプロセスのプロセスIDのリストを印刷します。std(in|out|err)
(既定値 - 異なる引数をテストするには、関数の数値引数を渡します.)それぞれ。シェル変数を$fd
この端末に関連付けられたファイル記述子番号に設定するか、標準記述子がない場合、または端末に関連付けられた引数がない場合はfalseを返します。
上記は、端末のセッションID(存在する場合)が見つからない限り、取得できる最も近い情報です。
ps -osid= -p"$$"
これにより、制御端末の所有者のpidが返されます(存在する場合)。
展示する:
echo "$$"; sh -c 'sh -c "ps -osid= -p\"\$$\""'
6023
6023
しかし、これらのことにのみ頼ることはできません。まったくそうではありません。望むより:
sh -acm 'IFS=\; i=0;eval "$0"' \
'[ "$i" -lt 5 ] && eval "$*"' \
'ps -opid -opgid -p"$$"' \
'sh -acm "$0" "$0" "$@" i=$((i+=1))'
PID PGID
28766 28766
PID PGID
28768 28768
PID PGID
28770 28770
PID PGID
28772 28772
PID PGID
28774 28774
願いより?私がこれらのプロセスを実行している対話型シェルはそのリストにもありません。各sh
サブプロセスは深さが5に達するまで独自のサブプロセスを開始し、各サブプロセスが深さに達するとps
PIDおよびPGID印刷を呼び出します。すべてプロセスは新しいPGIDを取得します。タスク制御は、端末がタスクをテストするより直接的な方法であることを除いて、端末と同様に対話型シェルに関連しています。