16

これを検索しましたが、すでに尋ねた人を見つけることができなかったので、ここに行きます.

!cmdWindows 7 の主力シェルとして IPython に切り替え始めています。 システム シェルにコマンドを渡す bang マジック ( ) が cmd.exe の代わりに PowerShell を使用するように構成したいと考えています。これにより、MS が行った拡張機能を利用できますが、%COMSPEC%PowerShell に変更する必要はありません (私の会社では、自動化のためにいくつかの CMD ベースの .BAT を使用しており、それらを壊したくありません)。

回答には以下の情報が必要ない場合があるため、質問をここの上部に投稿します。

  1. 何か不足していますか?IPython で構成ファイルを使用してシステム コマンド インタープリターを指定する方法はありますか?
  2. !1 の場合、そのプロセスに対してローカルなマシン スコープの環境変数を使用して、PowerShell 内から子プロセスを起動する方法がありませんか?

調査/テスト

IPython コードを調べるとos.system()、コマンドをシェルに送信するためにsubprocess.call(). os.system* は単に COMSPEC を使用し、subprocess* を使用して使用する実行可能ファイルを指定できるため、これはやや複雑になります。

PowerShell を読み込んで$env:comspec変数を設定し、そのシェル内から IPython を起動しようとしましたが、COMSPEC が設定されているように見えても、IPython 内でも CMD がまだ使用されているようです。

[PS] C:\> $env:comspec
C:\Windows\system32\cmd.exe
[PS] C:\> $env:comspec = 'powershell.exe'
[PS] C:\> $env:comspec
powershell.exe
[PS] C:\> & 'C:\Python33\Scripts\ipython3.exe'
Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 1.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import os; os.getenv('comspec')
Out[1]: 'powershell.exe'

In [2]: !gci
'gci' is not recognized as an internal or external command,
operable program or batch file.

In [3]: os.system('gci')
'gci' is not recognized as an internal or external command,
operable program or batch file.
Out[3]: 1

ローカルで変更された COMSPEC が IPython に (ローカルで変更を行った PowerShell プロセスの子として) 渡されているようにos.system見えますが、まだ永続的な設定を使用しているようです。

ユーザースコープの環境変数を変更するだけで済む場合に備えて、 を使用して同様のことを試しまし[Environment]::SetEnvironmentVariable("ComSpec", 'powershell.exe', [System.EnvironmentVariableTarget]::User)たが、それも機能しませんでした (上記と同じ結果 - os.getenv('ComSpec')powershell が表示されますが、!-ed コマンドが CMD に送信されます)。 .

マシンスコープの環境変数を変更すると、私が望んでいるように見えますが、前述の理由により、有効な解決策ではありません。

[PS] C:\> $env:comspec
C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
[PS] C:\> [Environment]::GetEnvironmentVariable('ComSpec','User')
[PS] C:\> [Environment]::GetEnvironmentVariable('ComSpec','Machine')
C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
[PS] C:\> & 'C:\Python33\Scripts\ipython3.exe'
Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 1.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: !gci env:ComSpec

Name                           Value
----                           -----
ComSpec                        C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe

これは実行可能な継続的な解決策ではないため、ConEmu* の設定をいじってさらにテストしました。Explicit executableを設定し、 Set ComSpec environment variable for child processes to selected value * flags でSettings > Startup > ComSpecを設定し、powershell.exe へのパスを指定することで、グローバル変数を変更せずにこれを行うことができましたが、そうではありません。その設定はグローバル(ConEmu内)であるため、ConEmuを使用して開いたCMDコンソールに悪影響を与えるかどうかを確認してください。PowerShell でプロセス/子ローカル、マシン スコープの環境変数を設定する方法がわからないため (そのようなことが可能な場合でも)、上記の質問 2 を質問するようになりました。

結局のところ、私の夢の目標は、IPython が構成ファイルを介してコマンドシェル インタープリターの仕様をサポートすることですが、それを行うためにos.system()使用されるものはありません。subprocess.call()テストのためにローカル コピー (a'la this Python Doc )でそれを置き換えることをいじくり回す予定ですが、誰かが既にそれで遊んでいる場合、またはそれを使用するよりも現在のモデルに十分な利点がある場合はsubprocess、私はそうではありません知っている、私はそれを聞いてうれしいです. これは Windows 以外のシステム ( GitHub )では既に行われているようですが、私はこの規模の Python に慣れていないので、その変更が Windows 側で使用された場合に他に何も壊れないとは断言できません。条件の、同様に。

脚注

ガッ!どうやら、質問を適切に文書化するには、10以上の評判が必要です。上記の投稿が許可されていないリンクは次のとおりです。

  • os.system - docs.python.org/3.3/library/os.html#os.system
  • サブプロセス - docs.python.org/3.3/library/subprocess.html
  • ConEmu - code.google.com/p/conemu-maximus5/
4

3 に答える 3

14

IPython のスクリプト マジックを使用して、PowerShell コマンドを実行できます。

魔法を定義する

IPython プロファイルipython_config.pyで、次の行を含めるように変更します。

c.ScriptMagics.script_magics = ['powershell']
c.ScriptMagics.script_paths = {
        'powershell':'powershell.exe -noprofile -command -'}

-command -コマンドとして stdin テキストを実行するように PowerShell に指示します。-noprofilePS プロファイルをロードする必要がある場合は省略できますが、遅くなります。

その後、スクリプト セル マジック%%powershellとして使用できます。

In [1]: %%powershell
   ...: 1..5
1
2
3
4
5

カスタムマジック

少し使いやすくするために、ライン マジックとセル マジックの両方で PowerShell コマンドを処理する独自のマジック関数を定義しました。(参照:独自のマジックの定義) これは、スクリプトを IPython プロファイルのスタートアップ フォルダーに配置することで自動的に読み込まれます。(つまり~\.ipython\profile_default\startup\05-powershell_magic.py)

from IPython.core.magic import register_line_cell_magic

from IPython import get_ipython
ipython = get_ipython()

@register_line_cell_magic
def ps(line, cell=None):
    "Magic that works both as %ps and as %%ps" 
    if cell is None:
        ipython.run_cell_magic('powershell', '--out posh_output' ,line)
        return posh_output.splitlines()
    else:
        return ipython.run_cell_magic('powershell', line, cell)

使用例

ライン マジックを使用し%psて出力を変数に返すには、次のようにします。

In [1]: ps_version = %ps $PSVersionTable.PSVersion.ToString()

In [2]: print(ps_version)
['2.0']

%%psセル マジックを使用してコンソールに出力するには:

In [3]: %%ps
   ...: gci c:\

    Directory: C:\

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d-r--         10/2/2013  10:39 AM            Program Files
d-r--         12/6/2013   1:44 PM            Program Files (x86)
d----          2/6/2014   4:33 PM            TEMP
d-r--        11/27/2013  11:10 AM            Users
d----         1/13/2014  11:21 AM            Windows

セルマジックは、次の変数に出力を送ることができます--out <variable name>:

In [4]: %%ps --out process_name_id
   ...: $procs = gps| select Name, ID
   ...: $procs| ConvertTo-Csv -NoType| select -skip 1

In [5]: import csv

In [6]: list(csv.reader(process_name_id.splitlines()))
Out[6]:
[['7+ Taskbar Numberer', '3400'],
 ['acrotray', '3668'],
 ['armsvc', '1772'],
 ['audiodg', '4160'],
 ['AutoHotkeyU64', '472'],
 ['chrome', '6276'],
 ...
于 2014-02-07T22:26:03.820 に答える