タグ別アーカイブ: PowerShell

PowerShell tr command

こんなページを見つけた
エクスプローラからコマンドプロンプトやPowerShellを開いたり, その逆をする方法のまとめ – Qiita [キータ]

うおぉ!アドレスバーから起動すれば cmd.exe のカレントディレクトリにできるのか。
minipoli 必要無いジャン…

ついでに Shift を押しながら右クリックすると

path_copy

知らなかった。
マジで minipoli 必要無いジャン orz…

いや、URI 変換コピーとかがあるからまだ戦える、かも。
なんか小物フリーソフトって本格的に終わってしまったよね。

ついでに。

#nautilus `pwd`
nautilus .

GNOME の Nautilus もドットでカレントディレクトリを開くことができた。
そりゃそうか、今まで上のコマンドを打っていた筆者はアホだったのか。

**********

ということで。
久々に Windows を起動したので PowerShell ネタを。

以前エイリアスで grep コマンドを利用できるようにしたので今回は tr でも。
完全に再現する必要は無いと思うけど正規表現くらいは使えるようにしたいな。

$input に Pipe から送られてくるデータが入っているらしい。
-replace ではなく -creplace なら大文字小文字を区別するようだ。
正規表現については勝手にやってくれる、と思う。

function global:Tr {
    Param([string]$s1, [string]$s2)
    $input -creplace $s1, $s2
}

profile

%USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
に追記、なんかアッサリ作れてしまったけど本当にコレでいいのかな?

command

正規表現も使える、筆者が使う範囲ならこれで十分だ。
sed は別の人がやってくれるだろう。

問題はリダイレクトすると文字列が BOM 付き UTF-16LE になってしまうこと…
せっかく高機能なのに普通に使おうとすると中途半端なんだよなぁ。

追記

UNIXの部屋 コマンド検索:tr (*BSD/Linux)

ちょっと勘違いしていたな…

まあいいか、sed の代わりにも使えるし。

Gedit for Windows part3

Gedit Windows 版から IronPython を起動する。
Python コードを開いて F5 キーを叩くと実行結果をボトムパネルに表示。
Gedit で Python スクリプトを debug – L’Isola di Niente
つまりコレを再現したい。

Gedit の Windows 版で External Tools が使えないのでソースコードを見る。
ちなみに External Tools も Python 製である。
8.11 fcntl — fcntl() および ioctl() システムコール
を使っていた、なるほどこれでは Windows では使えないわけだ。

前回は少し勘違いをしていたようで環境変数は External Tools が登録するようだ。
何にせよ Linux と Windows でまったく同じコードというのは不可能だよね。

とりあえず Python なんだから subprocess でなんとかならないか。
window オブジェクトからロケーションは得られるのだから強引にでも。

と思ってこんなプラグインを作ってみた。

ipyexec.gedit-plugin

[Gedit Plugin]
Loader=python
Module=ipyexec
IAge=2
Name=Iron Python Execute
Description=Iron Python Execute
Authors=sasakima-nao <sasakimanao@gmail.com>
Copyright=Copyright © 2013 sasakima-nao <sasakimanao@gmail.com>
Website=http://palepoli.skr.jp/

ipyexec.py

#-*- coding:utf-8 -*-

import gedit
import gtk
import os
import subprocess

IPYPATH = "C:\Program Files (x86)\IronPython 2.7\ipyw64.exe"

ui_str = """<ui>
    <menubar name="MenuBar">
        <menu name="ToolsMenu" action="Tools">
            <menuitem name="ipyexec" action="ipyexec"/>
        </menu>
    </menubar>
</ui>
"""

class IpyExecPlugin(gedit.Plugin):
    def __init__(self):
        gedit.Plugin.__init__(self)

    def activate(self, window):
        self._window = window
        manager = self._window.get_ui_manager()
        self._action_group = gtk.ActionGroup("IpyExecActions")
        # GtkActionEntry
        # name, stock_id, label, accelerator, tooltip, callback
        actions = [("ipyexec", None, "ipyexec", "F5", "ipyexec", self.on_ipyexec_activate)]
        self._action_group.add_actions(actions)
        manager.insert_action_group(self._action_group, -1)
        self._ui_id = manager.add_ui_from_string(ui_str)
        # Panel
        self.textview = gtk.TextView()
        self.textview.show()
        self.outputpanel = gtk.ScrolledWindow()
        self.outputpanel.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.outputpanel.set_shadow_type(gtk.SHADOW_IN)
        self.outputpanel.show()
        self.outputpanel.add(self.textview)
        bottom = self._window.get_bottom_panel()
        bottom.add_item(self.outputpanel, "Output", "Output")

    def deactivate(self, window):
        manager = self._window.get_ui_manager()
        manager.remove_ui(self._ui_id)
        manager.remove_action_group(self._action_group)
        manager.ensure_update()
        # Panel
        bottom = self._window.get_bottom_panel()
        bottom.remove_item(self.outputpanel)

    def update_ui(self, window):
        pass

    def on_ipyexec_activate(self, action):
        # Show Buttom Panel
        bottom = self._window.get_bottom_panel()
        bottom.show()
        # Buffer
        buf = self.textview.get_buffer()
        # Get full path
        view = self._window.get_active_view()
        doc = view.get_buffer()
        location = doc.get_location()
        path = location.get_path()
        # Popen
        popen = subprocess.Popen(
                [IPYPATH, path],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE )
        output = popen.communicate()
        if output[1]:
            buf.set_text("Do IronPython\n\n%s\nDone." % output[1])
        else:
            if output[0]:
                buf.set_text("Do IronPython\n\n%s\nDone." % output[0])
            else:
                buf.set_text("Do IronPython\n\nNo Output\n\nDone.")

ipyexec

なんとか動く、かなり手抜きくさいのはご了承。
External Tools と違って終了するまで値が戻ってこない仕様ですんで。

小物ならコレで問題ないけど Application クラスを使うとなると…
即座に stderr を検知したいけど、手段が解らないです。

拡張子判別をしてアプリを振り分ける手もあるけど私的にはコレでいい。
別の言語で起動させたい人はお好みに書き換えてください。

これ以上改造するにしても、GTK2, gconf, Python2, PyGtk…
本体及びプラグインの構成部品がことごとく既に開発終了しているという現実がね。
Gedit3 の Windows パッケージが出るならもう少し本気になるかも。

ということで。
Linux でも Windows でも動くことを考慮しなければプラグインは作れます。
ただ Windows で PyGtk を勉強しても他で何も役に立たない、しかも開発終了品。
なので他人に勧め辛いのが難点、Python の勉強にはなるけど。
もっとイイのを誰かに作ってほしいな(ぉい!

# 2013.11.09 追記
日本語出力ができなかった、日本語 Windows の stdout は cp932 なので変換。
それと output を別スレッドにして動作を判り易く改良してみた。
終了まで出力しないのは変わらないけど。

#-*- coding:utf8 -*-

import gedit
import gtk
import os
import subprocess
import glib

IPYPATH = "C:\Program Files (x86)\IronPython 2.7\ipyw64.exe"

ui_str = """<ui>
    <menubar name="MenuBar">
        <menu name="ToolsMenu" action="Tools">
            <menuitem name="ipyexec" action="ipyexec"/>
        </menu>
    </menubar>
</ui>
"""

class IpyExecPlugin(gedit.Plugin):
    def __init__(self):
        gedit.Plugin.__init__(self)

    def activate(self, window):
        self._window = window
        manager = self._window.get_ui_manager()
        self._action_group = gtk.ActionGroup("IpyExecActions")
        # GtkActionEntry
        # name, stock_id, label, accelerator, tooltip, callback
        actions = [("ipyexec", None, "ipyexec", "F5", "ipyexec", self.on_ipyexec_activate)]
        self._action_group.add_actions(actions)
        manager.insert_action_group(self._action_group, -1)
        self._ui_id = manager.add_ui_from_string(ui_str)
        # Panel
        self.textview = gtk.TextView()
        self.textview.show()
        self.outputpanel = gtk.ScrolledWindow()
        self.outputpanel.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.outputpanel.set_shadow_type(gtk.SHADOW_IN)
        self.outputpanel.show()
        self.outputpanel.add(self.textview)
        bottom = self._window.get_bottom_panel()
        bottom.add_item(self.outputpanel, "Output", "Output")

    def deactivate(self, window):
        manager = self._window.get_ui_manager()
        manager.remove_ui(self._ui_id)
        manager.remove_action_group(self._action_group)
        manager.ensure_update()
        # Panel
        bottom = self._window.get_bottom_panel()
        bottom.remove_item(self.outputpanel)

    def update_ui(self, window):
        pass

    def on_ipyexec_activate(self, action):
        # Show Buttom Panel
        bottom = self._window.get_bottom_panel()
        bottom.show()
        # Write
        buf = self.textview.get_buffer()
        buf.set_text("Do IronPython\n\n")
        glib.idle_add(self.on_idle)

    def on_idle(self):
        # Buffer
        buf = self.textview.get_buffer()
        it = buf.get_end_iter()
        # Get full path
        view = self._window.get_active_view()
        doc = view.get_buffer()
        location = doc.get_location()
        path = location.get_path()
        # Popen
        popen = subprocess.Popen(
                [IPYPATH, path],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE )
        output = popen.communicate()
        if output[1]:
            buf.insert(it, "%s\nError." % output[1])
        elif output[0]:
            #buf.insert(it, "%s\nDone." % output[0])
            s = unicode(output[0], encoding='cp932').encode("utf8")
            buf.insert(it, "%s\nDone." % s)
        else:
            buf.insert(it, "Done.")
        return False

####################

Gedit には grep 機能が無い?
元が Linux のエディタだよ、皆 grep コマンドを使っているからあるわけない。

だから WindowsPowerShell で Select-String コマンドを使いなさい。
つか grep というエイリアスを作ることもできる。
Windows PowerShell の機能

mkdir WindowsPowerShell
cd WindowsPowerShell
echo Set-Alias grep Select-String > Microsoft.PowerShell_profile.ps1

ドキュメントディレクトリでこんなバッチを動かせば一発よん。

grep

パイプによる stdout も受け付けるし grep コマンドとほぼ同様。
まさか Gedit で grep プラグインを探している偽 Linux 使いはいませんよね。

Windows 7 の PowerShell で遊んでみる

IronPython は楽しくて最高だけど Windows にデフォルトでは入っていない。
基本として OS デフォルト状態で動かせるアプリしか配布したくない私には少々問題だ。
アプリ配布で「まずコレを入れてくれ」ではアレほど馬鹿にしていた VB6 以前とカワンネ。

そうだ、Windows PowerShell という手があった。
Windows 7 ならデフォルトで入っているじゃないか。

地味に利用はしていたのだが、cd コマンドで移動して

rm *.zip

とかやって ZIP ファイルをまとめて削除したり kill コマンドを使ったりetc…
Linux と Windows を併用しているとソレが普通に、同じコマンド名が使えるところが嬉しい。
つか cmd.exe のコマンドなんてほとんど知らない…

しかし PowerShell はもっと強力で .NET がほぼフルで使えウインドウも造れるはず。
文法がイマイチ好きになれなかったけどもう少し突っ込んだ使い方をしてみよう。
検索すれば日本語での情報も IronPython よりは多い。

そういえば PowerShell では文字列のリダイレクトはどうなるのだろう?

echo あ > a.txt

は cmd.exe では当然のように Shift-JIS だが PowerShell では BOM 付き UTF-16LE に。

やっぱり文字列は UNICODE なのか、リダイレクトでは UTF-8 にはならないんだね。
リダイレクトするとUnicodeで出力されるとは… – もにっき
これだから内部と local が違う変態 OS は困る…

起動オプションは cmd.exe で以下を打ち込めば echo される。

powershell -?

ヘルプによると *.ps1 を読み込むにはフルパスか ./ 指定が必要。
まぁこれは bash でも同じなんだが、しかしやたら親切なエラー表示だなぁ。

PowerShell は通常 Multi Thread Apartment で起動する。
クリップボードとか STA(Single Thread Apartment) 属性が必要な場合は以下で起動。

powershell -sta

そうすると

[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.Clipboard]::SetDataObject("ほげ")

等ができる、-sta 指定しないとエラーになる、つまり WPF の利用なんかでも必須。
Windows PowerShell ISE から利用すれば自動で STA になるけど…

beep 音を鳴らす方法は何故か日本語で見つからなかった。

[console]::Beep()

音がショボイ、コッチのほうがいいかも

[System.Media.SystemSounds]::Beep.Play()

ここまでやって気が付いたけど…
*.ps1 ファイルを作ってもコンソールを出さないで利用する方法が無いみたい。
GUI を使うには物凄く向いていない、IronPython の代わりに使うのは無理かと。
やはりコイツはサーバー管理者向けですわ、まぁ何か思いついたら利用するべ。

よさげなサイト
PowerShell FAQ

こんなのもあるんだよね。
窓の杜 – 【NEWS】「PowerShell」v2の機能を拡張するモジュールパック「PowerShell Pack」が公開

PowerShell はなんとも 2

PowerShell をメニューから起動すると巨大なウインドウになって面食らう。
コレは右クリックしてプロパティから調節できるはずなんだけど…

psproperty

大きさを変更して「適用」するとフォントが太字に早変わり。
パス区切りもバックスラッシュになり Alt+半角/全角 を押しても日本語入力が不能に。
ワケワカンネェ!デフォルトのまま使うしか無いってこと?

と思ったけどメニューにあるショートカットをコピーして弄くるとこうなるっぽい。
本体から右クリックドラッグして直接ショートカットを作ったら普通にカスタマイズできた。
でも「デスクトップにショートカット作成」を利用するとアイコンが cmd.exe に。
わけわかんねぇ、Vista というか私の環境だけか?

画面バッファのサイズがスクロール範囲
ウインドのサイズが半角英数が何文字入力できるか(全角は半分)のようだ。
システム設定を使うにチェックを入れると起動位置は Windows が勝手に決める。
というか cmd.exe も同じなんですけどね。

まぁ標準出力なんだから cmd.exe から使えるんですけどね。

cmdpower

とにかく kill コマンドが使えるのが嬉しい、タスクマネージャより楽。
cmd.exe でもやれるんだろうけど使い方イマイチ解らないし。

でもファイルをドロップしても bash みたくパス名に展開してくれないなぁ…
まあ minipoli を使えばいいんですけど、D&Dは Windows のほうが本場じゃ?
Ctrl+Shift+C (V) という解りやすいコピペのショートカットもやはり無理か。

他に検索すると F7 でコマンド履歴とか見つかるけど上矢印キーのほうが楽だと思う。

そういえば UAC はどうなるの?と思って cp コマンドで system32 フォルダへ。
容赦なく拒否された、UAC ダイアログくらい出してよ、いやそれではリモート接続が…
「管理者として実行」をまずしなきゃいけないの? su なり sudo なりも真似してよ。
UAC が嫌われる原因の一つがよく解った。

PowerShell はなんとも

upman

VirtualBox 上の Ubuntu は三ヶ月置いたらこんなにイッパイ…
本当に Ubuntu は凄まじい勢いでアップデートを行っているなぁと。

vlgosic

どうしても同じ VL ゴシックの 9pt に見えないんだが何故だろう?
って画像にしたらアンチエイリアスが掛かってまったく同じに見えるわな。
実物はやはり違う、Windows では MS ゴシックでいくほうが良さそうだ。

さて環境の更新作業が終わったところで。

Windows Power Shell をインストール。
.NET なので最初の起動が当然遅い、SupewFetch が覚えるまでの我慢だ。

とりあえず cd のドライブ間移動で /d オプションが不要になったみたい。
つーか

pshell

ちょー!何コレ。
パス区切りは \ は当然だけど / でもいいとか、^/ でホームに戻るとか。
カレントディレクトリにあるスクリプトの実行は ./ を付加する必要があるとか。
おいおい、kill コマンドまで使えちゃったよ、何を考えているのコレ。

完全に UNIX からの乗り換えを意識しまくっている。
でもやっぱりアルファベットの大小文字の区別はしてくれないのね。

ところで Tab キーでの補完って cmd.exe でもできたんだ、知らなかった。

パスを通しておけば python と打つだけで普通に Python 端末にもなる。
でも Windows は UNIX 系のように実行ファイルが特定ディレクトリに固まっていない。
こうしたい場合は自前でパスを通さないと bash のようには簡単に使えない。
cmd.exe の代わりにシェル端末としても十分使えるようだ。

pspy

ググれば $ を使った変数や関数の書き方がすぐに見つかる。
けどそういうのは Python 等でやったほうが楽なので覚えても使わないかと。
UNIX のように必要な場面はあまり無いだろうと思う、書き方も面倒だし。

cmd.exe よりは圧倒的に使い道があるなと。
ただ .NET ではなくネイティブコードでコレを実現してほしかったなぁという感じ。
Vista 以前の Windows では遅すぎて使う気にならないだろうし。

Windows での Python はシステムには関係無いので遠慮無く 3.0 を使う。
とりあえず昔書いたスクリプトを動かしてみる、あっさりエラー。
print が文から式に変わったので括弧が必要になるのをお忘れなく。
Windows 版 Python 端末は Ctrl+Z で終了ですのでお間違いなく。