シェルスクリプトは、自分がシェルのCLIで呼び出されていることをどうやって知ることができますか?

シェルスクリプトは、自分がシェルのCLIで呼び出されていることをどうやって知ることができますか?

zshシェルのCLIから直接呼び出されるかどうかによって動作が異なるスクリプトを実装したいと思います。

最初はスクリプトが値iを取得してこれを行うことができると思いましたが、私の$-考えは間違っていました。

実際にコマンドラインで以下のスクリプトを実行すると、

#!/bin/zsh
printf -- '%s\n' "$-"

...私が得た出力にはi1が含まれていません。

私のシェルスクリプトでこの情報を見つける他の方法はありますか?

気づく:zshbash現在、台本を書いていますが、台本に対する答えが何なのか知りたいです。答えが異なる場合、OS私は主にLinuxとDarwinに興味があります。


1569Xもし気になる方がいらっしゃるなら、スクリプトの出力は次のようになります。

ベストアンサー1

$-iシェル自体がインタラクティブシェルの場合、プロンプトを発行する場合、端末でコマンドラインの入力と編集を許可する場合、ジョブ制御などを行う場合が含まれます。

スクリプトは通常、非対話型シェルによって解釈されます。スクリプトを./the-scriptまたはとして呼び出すと、zsh ./the-scriptインスタンスzshは対話型ではありません。対話型シェルがスクリプトを解釈する唯一の場合は、source ./the-scriptまたはなどのコードを使用して内部コードを解釈するように対話型シェルに指示するときですeval "$(<the-script)"

ここでは、ユーザーが端末を介して対話できるかどうかを知りたいのと同じように、端末内でスクリプトが呼び出されるかどうかを知りたいと思います。

[/コマンドtest(zshとbashと他のほとんどのBourne様シェルに組み込まれていますが、POSIXシステムではスタンドアロンコマンドとしても存在する必要があります)は、オペレータを介して-t通知できます。この-t演算子は、ファイル記述子である数値引数を使用します。

[ -t 0 ]または、test -t 0ファイル記述子 0 が端末デバイスで開いている場合は true を返します。ファイル記述子0標準入力、1は標準出力、2例標準エラー、他のすべてのfdには予約された特別な意味はありません。

したがって、スクリプトでは次のことができます。

if [ -t 0 ]; then
  echo "I (this script) am taking input from a terminal, so likely from a user"
fi

if [ -t 1 ]; then
  echo "My output goes to a terminal device, so will likely be seen by a user"
  [ -t 2 ] && echo errors also go there.
fi

入力および/または出力がターミナルデバイスの外部の他のファイルにリダイレクトされても、スクリプトがターミナルセッションで実行されていることを確認するには、スクリプトセッションに接続されているターミナルがあることを確認できます。例:

if { true <> /dev/tty; } 2> /dev/null; then
  echo "there's a terminal device attached to my session"
fi

どの端末デバイスかを知りたい場合は、次の操作を行います。

tty_on_stdin=$(tty)
tty_on_stderr=$(tty <&2)
{ tty_on_stdout=$(tty <&3); } 3>&1

(望むよりこの後続のQ&Afdで踊る理由3)。

controlling_tty=$(LC_ALL=C ps -o tty= -p "$$")
[ "$controlling_tty" = '?' ] || controlling_tty=/dev/$controlling_tty

¹以前test/[実装では、このパラメータはオプションであり、[ -t ]の略語でした[ -t 1 ]。 POSIX[ "$var" ]はと同じであるため、これは許可されません。それにもかかわらず、stdoutが端末にない場合でも、リテラルの場合にのみstdoutがttyに行くことを確認する[ -n "$var" ]ことがわかります。 。ksh93[ -t ]-tvar=-t; [ "$var" ]

おすすめ記事