世界を動かす技術を、日本語で。

Windows用Coreutils

概要

  • Windows でも UNIX系コマンド をネイティブに使用可能
  • Microsoft 公式が uutils/coreutils, findutils, grep を一体化
  • Linux, macOS, WSL と同じコマンド・パイプライン互換
  • WinGet やリリースページから簡単インストール
  • 一部コマンドは PowerShell/CMD のビルトインと競合注意

Windows向けUNIXコアユーティリティの概要

  • uutils/coreutils, findutils, grep をまとめた Microsoft公式ビルド
  • Linux, macOS, WSL, コンテナ, Windows 間でスクリプトやコマンドの移植性向上
  • 既存の シェルスクリプト無変換 でそのまま動作
  • 各コマンドは --help オプション対応、詳細な使い方確認可能
  • 現在は プレビュー版 として提供

インストール方法

  • WinGet によるインストール
    • コマンド例:winget install Microsoft.Coreutils
  • Release Page から最新版バイナリのダウンロードも可能

シェルでのコマンド競合

  • PowerShell 7.4以降 必須、旧バージョン非対応
  • CMD/PowerShell のビルトインコマンドと一部競合
    • 競合の有無は シェル種類、PATH順序、PowerShellのエイリアス で決定
  • 代表的な競合例
    • cat, cp, ls, rm, sort などは 動作可能 (一部PowerShellと競合)
    • dir, expand, more, paste, kill, timeout, whoami などは 非提供 または 競合で利用不可
    • find, sort, hostnameWindows組込版の拡張 として動作

Windows特有の注意点

  • CRLF改行
    • 通常は自動対応だが、 $でのパターンマッチやバイト数指定 に影響あり
  • /dev/nullの非対応
    • 代替として NUL を使用(例:find . -name "*.log" > NUL
  • POSIXシグナル未対応
    • SIGHUP, SIGPIPE, SIGUSR 等は利用不可、 Ctrl+C(SIGINT) は動作
  • パス区切り記号
    • /と**両方利用可能、出力は \区切りが多い
  • ファイル権限
    • POSIXパーミッション ではなく ACL で管理、一部コマンドは挙動やオプションが異なる
  • シンボリックリンク
    • 既存リンクの読取は可能、新規作成は 開発者モード または 管理者権限 が必要

提供されないコマンド

  • POSIX依存Windowsで無意味・競合するもの は非提供
    • 例: dd, dircolors, shred, sync, uname, chcon, chmod, chown, chroot, mkfifo, stty, who など

コントリビューション

  • バグ報告、プルリクエスト 歓迎
  • 詳細は CONTRIBUTING.md 参照
    • リポジトリ構成、uutils本家との変更フロー について記載

Hackerたちの意見

やっと来た!これは実際にワクワクするね… Linuxのポート(Cygwin、MSYS2、Git Bash)はどれも素晴らしいけど、どれか一つは常にパスに入れてる。でも、MSがそれをメンテナンスしてくれるなら(続けてくれると仮定して)、いいニュースだね。

つまり、dirはビルトインとの競合で出荷されないのに、echoとrmdirは競合してても出荷されるってこと?sortは競合がないと見なされるの?その論理は何なの?

AIがそう言った。

さっぱりわからない。これ、最初から壊れてるよ。少なくとも、今後どうやってこの混乱を改善するつもりなのか理由を説明してほしい。そうじゃないなら、やらない方がいいよ、扱いにくいなら。

CMDコマンドと競合する場合は出荷されないと思うけど、Powershellコマンドと競合する場合は大丈夫なんじゃないかな。

hex4def6が言ったように、DOSコマンドの競合は良くないアイデアだし、インタラクティブセッションでPowerShellのビルトインを上書きするのは(PSReadLineで)許容されるけど、あまり良いアイデアではない。私たちはDOS sortをオープンソースにして、DOS findコマンドのポートも公開した。スイートはヒューリスティックに基づいてGNU/DOSのバリアントに振り分けるんだ。

おそらく、いくつかのコマンドは、コマンドラインオプションなしで使うと両方のシステムで同じように動作するから互換性があるんだと思う。実装がDOSとUnixのオプションを区別できるんだろうね。

CMDとPowerShellでは、いくつかのコマンドがビルトインと名前が被ってる。Coreutilsのバージョンが動くかどうかは、シェル、PATHの順序、そして(PowerShellの場合は)エイリアステーブルによる。 うーん、これはあまり満足できないね。失敗の根本原因を推測しなくても実際に動く方法を示してくれればいいのに。

対象プログラムへのパスを完全に指定すれば、特に問題はないはずだよ。

一番面白いのは、PowerShellが何年も前からLinuxコマンドをWindowsの同等品にシムしてたから、たくさんのPowerShellと競合してるってこと。フラグが違ってたのにね。だから、いろんなシステムで「ls」は「dir」の動作に合わせて、dirのフラグだけを受け入れるんだ。でも、ここで新しいcoreutilsリリースを使ってるシステムだと、lsはlsのフラグを期待するよ!

もしかして、llmツールのためにPATHを使うってことかな?それが一番納得できる理由だと思ったんだけど。

既存のCMDバッチファイルやPowerShellスクリプト、アプリケーションの呼び出しを壊さずに、どうやってこれを解決するつもりなの?

AIエージェントをWindowsでより良く動かすための動機があるのかな?

確かに。エージェントがこれについて学ぶのにどれくらいかかるんだろうね。少なくとも1年はかかるよね?

目的は、macOSやLinuxから来た人たちに、彼らが慣れ親しんだCLIツールをもっと提供することだったんだ。つまり、エージェントは全然焦点じゃなかった。でも、もしそれが彼らの役に立つなら、それはもちろんいい追加のメリットだね。

Windowsは本当にCRLFを捨ててLFだけ使うべきだし、バックスラッシュをスラッシュに切り替えるべき。もっと言えば、すべてをフルPOSIXに切り替えた方がいい。PowerShellはCMDよりずっと良いけど、それだけじゃ足りない。WSLは一般的には素晴らしいけど、イライラする欠点もある。よく「壊滅的な」クラッシュが起きるし、ゾーン識別子ファイルには本当に困ってる。WSLで接続するとVSCodeの起動がすごく遅くなるし、今は二つのファイルシステムがある。これらの理由で、WSL1はWSL2よりも多くの面で良かった。

これが実現するとは思えないな、特に相手がMicrosoftだしね。

それなら、すべてをフルPOSIXに切り替えるのがいいけど、実際には無理だね。ほとんどのPOSIXの意味はカーネルから自然に生まれるし(またはカーネルレベルで強制・実行される)。Windowsは技術的にはいくつかのPOSIXの概念を提供してるけど、フルポートをするにはあまりにも多くの概念を削除しなきゃいけないから、やる価値がないと思う。例えば「すべてはファイル」という考え方や、単一のルートファイルシステムのレイアウト(確かカーネルレベルで深くセグメント化されてるよね)。

Windowsでは、テキストエディタやgitをLFを使うように設定して、テキストファイルをバイナリモードで書くことでCRLFを避けてる。CRLFを強制されるのはバッチファイルとクリップボードだけだったな。

... それよりも、全部をフルPOSIXに切り替えちゃえばいいのに。Interix[0]はこれをうまくやってたけど、MSFTが潰しちゃった。2000年にWindows 2000の下でGCCでGNUツールをコンパイルして、Interixでbashを動かしてたんだ。最高だったよ。 [0] https://en.wikipedia.org/wiki/Interix

心配しないで、いずれXenixが復活するから。CRLFは捨てられないよ、MicrosoftはAppleじゃないし。Windowsはバックスラッシュとスラッシュの両方を受け入れるけど、手動でどちらかを探す古いアプリケーションだけが間違えるんだ。

新しい名前のOSを作った方がいいかもね。既存のアプリケーションは動かないし、企業の顧客も使わないだろうし。

WindowsはUTF-16という珍しい存在でもあるんだ。「UTF-16はWindows APIやJava、Qtなど多くのプログラミング環境で使われている。UTF-16の可変長文字と、ほとんどの文字が可変長でないという事実(だから可変長はあまりテストされない)は、ソフトウェア、特にWindows自体に多くのバグを引き起こしている。」「UTF-16は、8ビットASCIIと互換性のないウェブで唯一(まだ)許可されているエンコーディングだ。ウェブでは人気がなく、公開ウェブページの0.004%未満で宣言されている(それでも、ウェブページはおそらくUTF-8も使っている)。対照的に、UTF-8は数年前に主流になり、2025年までに全ウェブページの99%を占めることになった。」 https://en.wikipedia.org/wiki/UTF-16

Windowsのほとんど(全部?)は実際にはスラッシュで動くんだ。ただ、ツールの多くはできるだけバックスラッシュに上書きしちゃうけどね。

「Windowsは本当にCRLFを捨ててLFだけにして、バックスラッシュをスラッシュに切り替えるべきだ。」ハハハ、面白いね。マジで言ってるの?Windowsやユーザーソフトがどれだけ壊れるか、全然わかってる?本当にMSに、Windowsのコア機能として後方互換性を築いてきたのに、無数のソフトウェアを壊させたいの?その変更が何も壊さないようにうまくまとめられる理想的なファンタジーがあるかもしれないけど、そんなことは絶対に無理だよ。もし魔法の杖でそれを実現できるなら、やってるけど、現実はそんなに甘くない。

Windowsは本当にCRLFを捨ててLFだけにして、バックスラッシュをスラッシュに切り替えるべきだ。{実用的な観点から言うと:} どこでもPascalスタイルの文字列に切り替えて、パス区切り文字みたいな特別な文字を必要なくすべきだと思う。(パスは今や文字列のリストになってるからね。)

ヘッダー、テール、tr、uniq、cutがあればよかったな。古い「gnuwin32」のバージョンをたくさんのWindowsマシンに持ち込んで使ってる。これらは、サクッとログ分析するための定番ツールなんだ。Powershellも使えるけど、やっぱりこれらのシンプルなツールに慣れ親しんでるし、UnixやLinux、Windowsのいろんな環境で使ってきた「筋肉記憶」があるから、手放すのは難しいんだよね。

そのコマンドも使って、出力をフィルタリングしたりAIエージェントにフィードしたりしてる。テールとヘッドはトークンを無駄にしないためのお気に入りだよ。派手なビルドログのメッセージが多すぎるからね。

Windowsは最近のGNUツールのまともなポートが不足してるよね。まだ古いのをいくつか使ってるけど、MSがtextutilsみたいな他のツールグループにも手を入れてくれたらいいな。

"head、tail、tr、uniq、cutが見たかったな。" プロジェクトにはそれら全部が含まれてるよ。もしかして、過去のことを言ってたの?

https://frippery.org/busybox/ winget install -e --id frippery.busybox-w32

サイトからの引用だけど、「64ビット実行ファイルbusybox64.exeを使うことでいくつかの利点がある。特に、かなり速くなることがある。」

エラーが出てる気がするか、単に「find」と「元のDOSコマンドの統合ポート」の意味が分からないだけかも。どのWindows NT系OSにも「%SystemRoot%\System32\find.exe」があるから、これは絶対に競合してるよね。それに、「findutils」の「find」コマンドは、ファイル内のテキストを探すための「元のDOSコマンド」とは全然機能が似てないし。ちなみに、Windowsでは「find.exe」じゃなくて「findstr.exe」を使った方がいいよ。こっちの方が圧倒的に効率的だから。偶然に気づいてからは、Windowsで「find」って言いたいときは「findstr」って打つように手を訓練したんだ。

実際に、私たちはDOS sortをオープンソースにして、DOS findコマンドのポートも公開した。スイートはヒューリスティックに基づいてGNU/DOSのバリアントに振り分けるんだ。インストーラーでは、呼び出しが曖昧な場合にデフォルトで使用するバリアントを選ぶことができるよ。

ripgrepを使わない理由は?

findは使わない方がいいよ、VoidtoolsのEverythingを使ってみて。NTFSの構造を検索して、ファイル名を瞬時に見つけてくれるから。これはLinuxのファイルシステムにはない数少ない機能の一つだね。

MSの人たちへ:Windowsでネイティブのzshをお願い!WSL2は素晴らしいけど、ネイティブのPOSIXの方がもっといいよね。もちろん、大きな取り組みだけど、POSIXが必要な人にとってWindowsを一流の開発プラットフォームにすることができる。

NTカーネルは完全なPOSIXセマンティクスを実装することはできないよ。そうするには、別のUN*Xクローンが必要になる。それは最悪だね。

ReFS -> ZFS バッチ、VBSを削除してPowerShell 5から7に切り替え、bashを追加 DSCをAnsibleに置き換え Windowsレジストリを削除 サービス用にsystemdに切り替え ユーザーのフォルダをhomeに、programdataをetcに、program filesをoptにリネーム ストア/wingetアプリを/usrにして、マイクロソフトLinuxサーバーハイブリッドと呼ぼう。