Launch-Software "Windows上でLinuxコマンドを実行する"

PowerShellからGit Bashコマンドを直接実行する

目次

はじめに

Summary: PowerShell上でGit Bashのコマンド群(diff, sed, grep, awk, xxd, fileなど)を実行するためのPowerShellスクリプト「Invoke-GitBash 」(Alias: gitbash)を紹介する。Windows環境でLinuxコマンドを気軽に利用したい、というニーズに応えてくれるだろう。

Windows環境で開発や作業をしていると、時としてLinux系のコマンドを使いたくなること、ないだろうか? ぼくはある。Linux系のコマンドとはたとえば、テキスト処理に便利なsedgrep、ファイルの差分比較に重宝するdiff、データ加工に強力なawkなどだ。これら日々の業務でよく使うコマンドはどれも、単機能でシンプルなデザインである一方、自前でPowerShellスクリプトとして実装するには案外複雑で、手間がかかる。というか、無理だ。

Windows環境でLinux系のコマンドを使う方法はいくつかある。今回は、Git for Windowsをインストールした際に同梱されるLinuxコマンド群を用いることにした。要件はシンプルだ。PowerShellからシェルを切り替えることなくGit Bashのコマンドを直接実行できるようにすること。それから、パイプラインからの入出力を経由してPowerShellの強力な機能とGit Bashのコマンドを組み合わせて使えるようにすることの2点だ。

以上が、PowerShellスクリプト「Invoke-GitBash 」を作った動機だ。このスクリプトはGit for Windowsをインストールした際に同梱されるGit Bashのコマンド群をPowerShellから直接実行できるようにする。これにより、Windows環境にいながら、diffgrepsedといった強力なLinuxコマンドを気軽に活用できるようになる。

前提条件

問題をとく

1. 問題を理解する

Windows環境でLinuxコマンドを利用する際の一般的な課題を整理する。

表:Windows環境でのLinuxコマンド利用に関する不満・問題点

分類 不満・問題点 対応方針
起動の手間 Git Bashを別途起動する必要がある。 PowerShellから直接実行できるようにしたい。
コマンドパスの管理 Git Bashのコマンドの実行ファイルパスを意識する必要がある。覚えていられない。 パス解決を自動化して、シンプルなコマンド実行を可能にする。
シェルの切り替え PowerShellとGit Bashの間でシェルの切り替えが必要になり、思考が中断される。集中できない。 統一されたPowerShell環境内でコマンドを実行できるようにする。
出力の扱い Git Bashコマンドの出力をPowerShellでスムーズに扱いにくい場合がある。 標準入出力をPowerShellのパイプラインで扱えるようにしたい。

2. 計画をたてる

PowerShellからGit Bashコマンドを直接実行するためのスクリプトの実装方針を立てる。

課題 対策計画
起動の迅速化 PowerShell関数としてGit Bashコマンドを呼び出すラッパーを作る。
パスの抽象化 Git for Windowsのインストールパスを自動検出するか、設定で指定できるようにする。
シームレスな統合 Git Bashコマンドの引数をそのまま渡して、結果をPowerShellのストリームに返す。
PowerShellとの連携 パイプラインを経由した入出力(標準入出力)に対応する。

Note: 今回は、Git Bashコマンドの出力はPowerShellオブジェクトとして扱うようにはせず、テキストとしてそのまま出力する。(たくさんあるGit BashコマンドのすべてをPowerShellオブジェクトとして扱う変換を実装するのは、ぼくには荷が重いためだ。)

3. 計画を実行する

インストール

PowerShellスクリプト「Invoke-GitBash (Alias:gitbash)」をインストールする。

  1. pwsh-sketchesのインストール
  2. ドットソースで関数を読み込み
    • . path/to/the/pwsh-sketches/operator-minimum.ps1
      • PowerShellの文字エンコーディングを「UTF-8」に設定する
    • . path/to/the/pwsh-sketches/src/Invoke-GitBash_function.ps1
    • PowerShellのプロファイル ($PROFILE) にこれら行を追加しておくと、PowerShell起動時に自動的に関数が読み込まれて便利だ
  3. 動作確認
    • man Invoke-GitBashまたはman gitbash を実行して、ヘルプが表示されるか確認する

実行

Invoke-GitBash (Alias:gitbash)」を実際に使ってみる。 基本的な使い方は、Invoke-GitBash の後に、(サブコマンドのように)実行したいGit Bashコマンドとその引数を続ければいい。

例1: lsコマンドでファイル一覧を表示

Invoke-GitBash ls -la

これはGit Bashで ls を実行するのと同じ結果になる。 以下のように別名を用いてもいい。以降、別名を用いて解説する。

gitbash ls -la

例2: diffコマンドでファイルの差分を表示

ファイルfile1.txtfile2.txtを作る。

file1.txt:

line 1
line 2
line 3

file2.txt:

line 1
line A
line 3
line 4

以下のコマンドで差分を表示する。

gitbash diff file1.txt file2.txt

出力:

2c2
< line 2
---
> line A
3a4
> line 4

引数も指定できる。たとえば、-uオプションを指定して差分を表示する場合は、以下のようにする。

gitbash diff file1.txt file2.txt -u

出力:

--- file1.txt     2025-06-16 05:49:10.790945100 +0900
+++ file2.txt     2025-06-16 05:49:19.351187500 +0900
@@ -1,3 +1,4 @@
 line 1
-line 2
+line A
 line 3
+line 4

ただし、Git Bashのコマンド引数はPowerShellの引数と競合する場合があるので、注意が必要だ。

gitbash diff file1.txt file2.txt -p

出力(エラー):

Invoke-GitBash: Parameter cannot be processed because the parameter name 'p' is ambiguous. Possible matches include: -ProgressAction -PipelineVariable.

この場合、PowerShellの引数と競合しないように、引数をダブルクォートで囲む。(めんどうだけれど。)

gitbash diff file1.txt file2.txt "-p"

出力:

*** file1.txt     Mon Jun 16 05:49:10 2025
--- file2.txt     Mon Jun 16 05:49:19 2025
***************
*** 1,3 ****
  line 1
! line 2
  line 3
--- 1,4 ----
  line 1
! line A
  line 3
+ line 4

例3: grepコマンドで文字列を検索

a.txtというファイルを作って、以下の内容を記述してみよう。

a.txt:

apple
banana
cherry
apple pie

appleを含む行を検索する。

gitbash grep apple a.txt

出力:

apple
apple pie

例4: sedコマンドでテキスト置換

a.txtの「hello」を「world」に置換して表示する(元のファイルは変更されない点に注目。)

a.txt:

hello world
hello powershell

実行してみる。

gitbash sed 's/hello/world/g' a.txt

出力:

world world
world powershell

パイプラインをつなげることもできる。出力は上と同じだ。

gitbash cat a.txt | gitbash sed 's;hello;world;'

PowerShellコマンドの出力結果もパイプライン経由で受け渡しできる。

Get-Content a.txt | gitbash sed 's;hello;world;'

例5: awkコマンドでデータを処理

data.txtというファイルを作って、以下の内容を記述する。

data.txt:

Name,Age,City
Alice,30,New York
Bob,24,London
Charlie,35,Paris

カンマ区切りの2列目(Age)だけを表示してみよう。

gitbash awk -F, '{print $2}' data.txt

出力:

ParserError:
Line |
   1 |  gitbash awk -F, '{print $2}' data.txt
     |                ~
     | Missing argument in parameter list.

おっと、エラーだ。引数の-F,のカンマがPowerShellの配列区切りと競合している。これを回避するために、引数をクォートで囲む必要がある。このあたりは直観的ではないが、そういう仕様だと思ってあきらめる。

gitbash awk "-F," '{print $2}' data.txt

出力:

Age
30
24
35

事前にカンマ区切りでなく半角スペース区切りにしておく手もある(シンプルなCSVデータに限るが)。こちらは、(いちいちgitbashと打つのが面倒な点以外は)おおよそLinuxのawkコマンドと同じように使える。

Get-Content data.txt | gitbash sed 's;,; ;g' | gitbash awk '{print $2}'

出力:

Age
30
24
35

例6: xxdコマンドでバイナリダンプを表示

任意のバイナリファイル(例: image.jpgtest.bin)をダンプ表示する。

gitbash xxd your_binary_file.bin | Select-Object -First 10

Select-Object -First 10は、出力が大量になるのを防ぐために、最初の10行だけ表示するPowerShellのコマンドだ。)

例7: fileコマンドでファイルの種類を識別

gitbash file *.*
gitbash file your_document.pdf
gitbash file your_script.sh

Invoke-GitBash (Alias:gitbash)を使うことで、PowerShellのプロンプトから直接、Git Bashに含まれる強力なGNUコマンド群をシームレスに利用できる。使えるコマンドのリストは、gitbash単独、またはgitbash showで確認できる。ぼくの環境での実行結果を以下に示す。

gitbash show

出力:

'[.exe'                      gpg-connect-agent.exe    rview.exe
 addgnupghome                gpg-error.exe            rvim.exe
 applygnupgdefaults          gpg-wks-client.exe       scp.exe
 arch.exe                    gpg-wks-server.exe       sdiff.exe
 astextplain                 gpg.exe                  sed.exe
 awk.exe                     gpgconf.exe              seq.exe
 b2sum.exe                   gpgparsemail.exe         setfacl.exe
 backup                      gpgscm.exe               setmetamode.exe
 base32.exe                  gpgsm.exe                sexp-conv.exe
 base64.exe                  gpgsplit.exe             sftp.exe
 basename.exe                gpgtar.exe               sh.exe
 basenc.exe                  gpgv.exe                 sha1sum.exe
 bash.exe                    grep.exe                 sha224sum.exe
 bashbug                     groups.exe               sha256sum.exe
 bunzip2.exe                 gunzip                   sha384sum.exe
 bzcat.exe                   gzexe                    sha512sum.exe
 bzcmp                       gzip.exe                 shred.exe
 bzdiff                      head.exe                 shuf.exe
 bzegrep                     hmac256.exe              sleep.exe
 bzfgrep                     hostid.exe               sort.exe
 bzgrep                      hostname.exe             split.exe
 bzip2.exe                   iconv.exe                ssh-add.exe
 bzip2recover.exe            id.exe                   ssh-agent.exe
 bzless                      infocmp.exe              ssh-copy-id
 c_rehash                    infotocap.exe            ssh-keygen.exe
 captoinfo.exe               install.exe              ssh-keyscan.exe
 cat.exe                     join.exe                 ssh-pageant.exe
 chattr.exe                  kbxutil.exe              ssh.exe
 chcon.exe                   kill.exe                 ssp.exe
 chgrp.exe                   ldd.exe                  start
 chmod.exe                   ldh.exe                  stat.exe
 chown.exe                   less.exe                 stdbuf.exe
 chroot.exe                  lessecho.exe             strace.exe
 cksum.exe                   lesskey.exe              stty.exe
 clear.exe                   link.exe                 sum.exe
 cmp.exe                     ln.exe                   sync.exe
 column.exe                  locale.exe               tabs.exe
 comm.exe                    locate.exe               tac.exe
 core_perl                   logname.exe              tail.exe
 cp.exe                      ls.exe                   tar.exe
 csplit.exe                  lsattr.exe               tee.exe
 cut.exe                     mac2unix.exe             test.exe
 cygcheck.exe                md5sum.exe               tic.exe
 cygpath.exe                 minidumper.exe           tig.exe
 cygwin-console-helper.exe   mintheme                 timeout.exe
 d2u.exe                     mintty.exe               toe.exe
 dash.exe                    mkdir.exe                touch.exe
 date.exe                    mkfifo.exe               tput.exe
 dd.exe                      mkgroup.exe              tr.exe
 df.exe                      mknod.exe                true.exe
 diff.exe                    mkpasswd.exe             truncate.exe
 diff3.exe                   mktemp.exe               trust.exe
 dir.exe                     mount.exe                tset.exe
 dircolors.exe               mpicalc.exe              tsort.exe
 dirmngr-client.exe          mv.exe                   tty.exe
 dirmngr.exe                 nano.exe                 tzset.exe
 dirname.exe                 nettle-hash.exe          u2d.exe
 docx2txt                    nettle-lfib-stream.exe   umount.exe
 docx2txt.pl                 nettle-pbkdf2.exe        uname.exe
 dos2unix.exe                newgrp.exe               uncompress
 du.exe                      nice.exe                 unexpand.exe
 dumpsexp.exe                nl.exe                   uniq.exe
 echo.exe                    nohup.exe                unix2dos.exe
 egrep                       notepad                  unix2mac.exe
 env.exe                     nproc.exe                unlink.exe
 ex.exe                      numfmt.exe               unzip.exe
 expand.exe                  od.exe                   unzipsfx.exe
 expr.exe                    openssl.exe              update-ca-trust
 factor.exe                  p11-kit.exe              updatedb
 false.exe                   passwd.exe               users.exe
 fgrep                       paste.exe                vdir.exe
 file.exe                    patch.exe                vendor_perl
 find.exe                    pathchk.exe              vi
 findssl.sh                  perl.exe                 view.exe
 fmt.exe                     perl5.38.2.exe           vim.exe
 fold.exe                    pinentry-w32.exe         vimdiff.exe
 funzip.exe                  pinentry.exe             vimtutor
 gawk-5.0.0.exe              pinky.exe                watchgnupg.exe
 gawk.exe                    pkcs1-conv.exe           wc.exe
 gencat.exe                  pldd.exe                 which.exe
 getconf.exe                 pluginviewer.exe         who.exe
 getemojis                   pr.exe                   whoami.exe
 getfacl.exe                 printenv.exe             winpty-agent.exe
 getflags                    printf.exe               winpty-debugserver.exe
 getopt.exe                  profiler.exe             winpty.exe
 git-flow                    ps.exe                   wordpad
 git-flow-bugfix             psl-make-dafsa           xargs.exe
 git-flow-config             psl.exe                  xxd.exe
 git-flow-feature            ptx.exe                  yat2m.exe
 git-flow-hotfix             pwd.exe                  yes.exe
 git-flow-init               readlink.exe             zcat
 git-flow-log                realpath.exe             zcmp
 git-flow-release            rebase.exe               zdiff
 git-flow-support            rebaseall                zegrep
 git-flow-version            regtool.exe              zfgrep
 gitflow-common              reset.exe                zforce
 gitflow-shFlags             restore                  zgrep
 gkill.exe                   rm.exe                   zipgrep
 gmondump.exe                rmdir.exe                zipinfo.exe
 gpg-agent.exe               rnano.exe                zless
 gpg-card.exe                runcon.exe               znew

4. ふりかえり

今回紹介したInvoke-GitBash コマンドは、Windows環境でLinuxコマンドをより手軽に利用するためのものだ。その狙いは以下の4点に集約される。

  1. 起動の手間の削減: Git Bashを別途起動する手間をなくし、PowerShellから直接実行可能にする。
  2. シームレスな統合: PowerShellのコマンドライン環境にGit Bashコマンドを統合し、自然な形で利用できるようにする。
  3. 強力なツールの活用: diff, sed, grep, awk, xxd, fileといった日常的に役立つLinuxコマンド群を簡単に利用できるようにする。
  4. 作業効率の向上: シェルの切り替えによる思考の中断を減らし、スムーズな作業フローを実現する。

これらの課題はおおよそ満たされて、Invoke-GitBash コマンドは、Windows上でLinuxコマンドを多用するぼくのようなユーザーにとって、非常に有用なツールとなっている。

課題 結果 評価
起動の手間 PowerShellから直接Git Bashコマンドを実行可能だ。
コマンドパスの管理 Invoke-GitBash がGit Bashの実行パスを解決してくれるから、ぼくは意識しなくていい。
シェルの切り替え PowerShell環境内で完結するから、シェルの切り替えが不要だ。
出力の扱い Git BashコマンドとPowerShellの入出力はパイプラインで受け渡しできる。

用語

読者の理解と学習をより深めるための、リンクやショートカットを活用した効率化の観点でのいくつかの技術用語:

CLI(コマンドラインインターフェース)

文字でコンピューターに指示を出す方法。マウスでアイコンをクリックするGUI(グラフィカルユーザーインターフェース)とは異なり、キーボードで命令(コマンド)を入力して、ファイルを開いたり、プログラムを実行したりする。このブログで紹介するのは主にCLIを用いた方法。

別名(エイリアス:Aliases)

PowerShellやその他のシェルで、頻繁に使うコマンドやスクリプトに短縮名(エイリアス)を設定する仕組み。今回、「Invoke-GitBash 」のエイリアス(別名)は「gitbash」とした。他に考えた候補はigbibashgbashpbashpwbashなどがある。いずれも試してみたが、1日後に覚えていたのはgitbashのみだったので、文字数は少々多いが、これを採用した。