2011-12-16 3 views
7

私のPerlスクリプトを実行したスクリプト、プログラム、またはシェルはどのようにして決められますか?私のPerlスクリプトを実行したスクリプト、プログラム、またはシェルを知るにはどうすればよいですか?

例:シェルから実行すると人間の目に見える出力(シェルの種類ごとにカスタマイズ)、別のperlスクリプトからスクリプトとして呼び出された場合の出力の種類、および実行された場合の機械可読形式継続的な統合サーバーなどのプログラム

動機づけ:どのシェルがそれを実行するかに基づいて出力を変更するツールがあります。私は通常、この動作をスクリプトのオプションとして実装しますが、このツールの設計ではオプションが許可されていません。他のシェルには、実行中のシェルを示す環境変数があります。私はPowershellをサポートするためのパッチに取り組んでいますが、これには特別な変数はありません。

編集:これらの回答の多くは、Linux固有のものです。 Unfortuantely、PowershellはWindows用です。 getppid$ENV{SHELL}という変数があり、この場合はpsに逃げることはできません。このスクリプトはクロスプラットフォームで実行する必要があります。

+0

私は理解していません - あなたはその場合親プロセスを見てはいけませんか? – x0n

+0

STDOUTがターミナル( '-t')であるかどうかを調べることができます。そうであれば、連続的な統合デーモンではなく、インタラクティブシェルから呼び出されたものとみなします。しかし、この共通のテクニックは、個別の可能性のある親の出力をカスタマイズすることについては言及していませんが(とにかく、間違った欲求があると思います)。 – pilcrow

+0

忘れてしまいましたが、通常、シェルが実行中のシェルを示すためにシェルまたはユーザーが設定する環境変数を探します。 Powershellでは、そのような環境変数はありません。 –

答えて

1

環境によっては、環境変数から取得することができます。次のコードを考えてみましょう:私のUbuntuシステムに

/usr/bin/perl -MData::Dumper -e 'print Dumper(\%ENV);' | grep sh 

を、それは私を取得します。

'SHELL' => '/bin/bash', 

だから私はそれが私はbashシェルからPerlを実行しているよと言うと思います。他に何かを使用すると、SHELL変数がヒントを与えるかもしれません。

しかし、あなたがbashであることを知っているとしましょうが、perlはサブシェルから実行されています。そして、試してみてください。

/bin/sh -c "/usr/bin/perl -MData::Dumper -e 'print Dumper(\%ENV);'" | grep sh 

をあなたが見つける:

 '_' => '/bin/sh', 
     'SHELL' => '/bin/bash', 

ので、シェルはまだbashのですが、bashは、シェルまたはスクリプトの絶対ファイル名が実行されて表示され、変数$_があり、これかもしれませんまた、貴重なヒントを与える。同様に、他の環境では、恐らく有用なヒントを与えるべきであるperl %ENVハッシュに手がかりが残っているでしょう。

+0

ああ、ついに私がdownvotedになった理由を理解した。これまでPowershellタグは見ていませんでした。私の悪い。 –

+0

私はあなたを落とした人ではありませんでしたが、PowerShellが動作していることを伝える環境変数が大好きです。残念ながら、Powershellにはそのような変数はありません。スクリプトは環境を使用して、他のシェルタイプの出力内容を決定します。 –

+0

http://vlaurie.com/computers2/Articles/environment-variables-windows-vista-7.htm COMSPECがデフォルトでcmd.exeを指しているようです。おそらくPowerShellの実行時にPowerShellの実行ファイルを指しているのでしょうか?もしそうなら、あなたはCygwinやそれに類するものを含め、環境から実行時環境を把握できるはずです。 –

5

getppid()を使用しています。 child.plにこのスニペットを取る:あなたは、コマンドラインから実行した場合

my $ppid = getppid(); 
system("ps --no-headers $ppid"); 

systemは、(とりわけ)bashまたは類似したが表示されます。別のスクリプトでsystem("perl child.pl");で実行します。 parent.plと表示され、perl parent.plが実行されていることがわかります。

my $ppid = getppid(); 
my $ps = `ps --no-headers -o cmd $ppid`; 
chomp $ps; 

EDIT:このアプローチに代わる、あなたへのソフトリンクを作成するかもしれません(正しいps構文については池上のおかげで)引数を持つプロセスの名前だけをキャプチャする

異なるコンテキストで異なるリンクを使用してスクリプトにアクセスし、$0を調べて、その周りにロジックを構築してください。

+2

もう少し信頼できる: 'chomp(my $ parent_name = \' ps --no-headers -o cmd $ ppid \ ');' – ikegami

+0

@ikegami:ありがとう。私はそのフォーマットを指定する方法を知りませんでした。 – flesk

+0

残念ながら、WindowsのPerlは 'getppid()'をサポートしておらず、 'ps'への可能性もありません。 : –

3

私はあなたの目標を達成するために別のアプローチを提案します。文脈を推測するのではなく、より明示的にする。それぞれのユースケースは完全に分離されているため、3つの異なるインタフェースがあります。

  1. Perlプログラム内で呼び出せる関数です。これはおそらくPerlのデータ構造を返すでしょう。これは、スクリプト出力を解析するよりはるかに簡単で、高速で、信頼性が高いです。また、スクリプトの基礎となります。

  2. 現在のシェル用に出力するスクリプト。 $ENV{SHELL}を見ると、実行中のシェルを見つけることができます。ボーナスポイントの場合は、明示的に上書きするスイッチを指定します。

  3. 継続的インテグレーションサーバーなどの非Perlプログラム内で呼び出すことができ、マシンが読み取り可能な出力を発行できるスクリプト。 XMLおよび/またはJSONなどを使用します。

2と3は、それぞれがその特定のニーズに合わせて調整された1

から出てくるデータをフォーマットするだけの薄いラッパーになります。それぞれはヒューリスティックなしで動作します。それぞれは、コンテキストを推測しようとするよりもはるかに簡単で、ユーザーが望むものです。

2と3を分けることができない場合は、継続的な統合サーバーに環境変数を設定し、それを探しさせてください。

+0

合意、一般的な場合。私が言及したように、上記は、この技術の可能な応用の単なる例であった。この場合、スクリプトはシェルスクリプトを発行し、他のツールは、スクリプトを呼び出すシェルに対して適切な種類のシェルスクリプトを発行することを期待しています。ほとんどの他のシェルでは、どのシェルを使用するかを示す環境変数があります。 Powershellはそのような変数を与えません。 –

1

これはPowerShell v2.0を搭載したWindows XP上にありますので、塩分をとっておいてください。 cmd.exeシェルで

、私が手:

PSModulePath=C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\

を一方PowerShellコンソールウィンドウに、私が取得:

E:\Home\userはどこ私の "マイドキュメント" フォルダです

PSModulePath=E:\Home\user\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsP owerShell\v1.0\Modules\

です。したがって、1つのヒューリスティックは、PSModulePathにユーザ依存パスが含まれているかどうかをチェックすることです。また

は、コンソールウィンドウに、私が取得:環境中の

!::=::\

。 PowerShellのISEから、私は得る:

!::=::\ 
!C:=C:\Documents and Settings\user
+0

+1 - ああ、だめだ。私はあなたの答えに気付かなかった。私は同じことを考え出しただけです。ところで、それはpowershell 1.0ではない - v1はモジュールをサポートしていない。 %windir%の下のパスは、powershellのv1、v2、およびv3ではv1.0です。 – x0n

1

あなたはPowerShellの2.0以上(最も可能性が高い)を実行している場合は、環境変数%psmodulepath%を調べることによって、親プロセスとしてシェルを推測することができます。デフォルトでは、%windir%\system32\windowspowershell\v1.0\modulesのシステムモジュールを指しています。変数cmd.exeを調べると、これが表示されます。

ただし、PowerShellが起動すると、ユーザーのデフォルトのモジュール検索パスの前に、この環境変数(%userprofile%\documents\windowspowershell\modules)が追加されます。これは子プロセスによって継承されます。したがって、あなたのロジックは、%psmodulepath%が%userprofile%で始まってpowershell 2.0以上を検出するかどうかをテストすることです。モジュールをサポートしていないため、PowerShell 1.0では動作しません。

関連する問題