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系のコマンドとはたとえば、テキスト処理に便利なsed
やgrep
、ファイルの差分比較に重宝する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環境にいながら、diff
やgrep
やsed
といった強力なLinuxコマンドを気軽に活用できるようになる。
前提条件
- ✓ 自家製スクリプト:pwsh-sketchesのインストール
- ✓ Git for Windowsのインストール
- ✓ 検証した環境はこちら
問題をとく
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
)」をインストールする。
- pwsh-sketchesのインストール
- ドットソースで関数を読み込み
. path/to/the/pwsh-sketches/operator-minimum.ps1
- PowerShellの文字エンコーディングを「UTF-8」に設定する
. path/to/the/pwsh-sketches/src/Invoke-GitBash_function.ps1
- PowerShellのプロファイル (
$PROFILE
) にこれら行を追加しておくと、PowerShell起動時に自動的に関数が読み込まれて便利だ
- 動作確認
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.txt
とfile2.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.jpg
やtest.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点に集約される。
- 起動の手間の削減: Git Bashを別途起動する手間をなくし、PowerShellから直接実行可能にする。
- シームレスな統合: PowerShellのコマンドライン環境にGit Bashコマンドを統合し、自然な形で利用できるようにする。
- 強力なツールの活用:
diff
,sed
,grep
,awk
,xxd
,file
といった日常的に役立つLinuxコマンド群を簡単に利用できるようにする。 - 作業効率の向上: シェルの切り替えによる思考の中断を減らし、スムーズな作業フローを実現する。
これらの課題はおおよそ満たされて、Invoke-GitBash コマンドは、Windows上でLinuxコマンドを多用するぼくのようなユーザーにとって、非常に有用なツールとなっている。
課題 | 結果 | 評価 |
---|---|---|
起動の手間 | PowerShellから直接Git Bashコマンドを実行可能だ。 | ✅ |
コマンドパスの管理 | Invoke-GitBash がGit Bashの実行パスを解決してくれるから、ぼくは意識しなくていい。 | ✅ |
シェルの切り替え | PowerShell環境内で完結するから、シェルの切り替えが不要だ。 | ✅ |
出力の扱い | Git BashコマンドとPowerShellの入出力はパイプラインで受け渡しできる。 | ✅ |
用語
読者の理解と学習をより深めるための、リンクやショートカットを活用した効率化の観点でのいくつかの技術用語:
- CLI(コマンドラインインターフェース)
-
文字でコンピューターに指示を出す方法。マウスでアイコンをクリックするGUI(グラフィカルユーザーインターフェース)とは異なり、キーボードで命令(コマンド)を入力して、ファイルを開いたり、プログラムを実行したりする。このブログで紹介するのは主にCLIを用いた方法。
- 別名(エイリアス:Aliases)
-
PowerShellやその他のシェルで、頻繁に使うコマンドやスクリプトに短縮名(エイリアス)を設定する仕組み。今回、「Invoke-GitBash 」のエイリアス(別名)は「
gitbash
」とした。他に考えた候補はigb
、ibash
、gbash
、pbash
、pwbash
などがある。いずれも試してみたが、1日後に覚えていたのはgitbash
のみだったので、文字数は少々多いが、これを採用した。