MSYS2とWindowsのコマンド、PowerShellのエイリアスが衝突する

前回はPowerShellで「MSYS2」を利用する場合に、イラッとするポイントを回避するための設定を取り上げた。ある程度の使い方であれば、前回紹介した方法で結構使えると思う。

そもそもどういった点が問題になるのかと言うと、MSYS2のコマンドを使う場合には主に次の2つのポイントでイラッとする。

  • MSYS2のパスよりもWindowsのシステムパスのほうが優先度が高い。このため、Windowsシステムにすでに存在するコマンドと同名のコマンドは、MSYS2のコマンドではなくWindowsのコマンドが実行される
  • MSYS2のコマンドよりも、PowerShellのエイリアスのほうが優先度が高い。このため、PowerShellのデフォルトエイリアスに存在する名前と同名のコマンドは、MSYS2のコマンドではなくWindowsのコマンドが実行される


さらに面倒なことに、このどちらにも該当するコマンドも存在している。例えば、sortコマンドは、MSYS2 (Linux)のsortコマンドを実行しようとするとPowerShellのエイリアスが実行されたり、Windowsシステムコマンドのほうのsort.exeが実行されたりと、なかなかイラッとするのだ。

Windowsのコマンドとは

Windowsでは次のようなパスがシステムパスとして設定されている。次のスクリーンショットの上から4つに特に注目していただきたい。OpenSSHはWindowsのオプション機能を後から有効化したときに追加されたもの、PowerShellとdotnetのパスもそれぞれインストールしたときに追加されたものだ。

システムの環境変数Path

良い機会なので、それぞれのパスにどのようなコマンドが存在しているのかを紹介しておく。やや長くなるが、MSYS2の活用を模索していくのであれば、Windows側のコマンドも把握しておく必要がある。ざっとでよいのでどんな名前のコマンドがあるのか見ておいてほしい。

C:\Windows\system32\
agentactivationruntimestarter.exe、AgentService.exe、aitstatic.exe、alg.exe、AppHostRegistrationVerifier.exe、appidcertstorecheck.exe、appidpolicyconverter.exe、appidtel.exe、ApplicationFrameHost.exe、ApplySettingsTemplateCatalog.exe、ApplyTrustOffline.exe、ApproveChildRequest.exe、AppVClient.exe、AppVDllSurrogate.exe、AppVNice.exe、AppVShNotify.exe、AssignedAccessGuard.exe、at.exe、AtBroker.exe、attrib.exe、audiodg.exe、auditpol.exe、AuthHost.exe、autochk.exe、autoconv.exe、autofmt.exe、AxInstUI.exe、baaupdate.exe、backgroundTaskHost.exe、BackgroundTransferHost.exe、bash.exe、bcdboot.exe、bcdedit.exe、bdechangepin.exe、BdeHdCfg.exe、BdeUISrv.exe、bdeunlock.exe、BioIso.exe、BitLockerDeviceEncryption.exe、BitLockerWizard.exe、BitLockerWizardElev.exe、bitsadmin.exe、bootcfg.exe、bootim.exe、bootsect.exe、bridgeunattend.exe、browser_broker.exe、browserexport.exe、bthudtask.exe、ByteCodeGenerator.exe、cacls.exe、calc.exe、CameraSettingsUIHost.exe、CastSrv.exe、CertEnrollCtrl.exe 、certreq.exe、certutil.exe、CExecSvc.exe、change.exe、changepk.exe、charmap.exe、chcp.com、CheckNetIsolation.exe、chglogon.exe、chgport.exe、chgusr.exe、chkdsk.exe、chkntfs.exe、choice.exe、CIDiag.exe、cipher.exe、cleanmgr.exe、cliconfg.exe、clip.exe、ClipRenew.exe、ClipUp.exe、CloudExperienceHostBroker.exe、CloudNotifications.exe、cmd.exe、cmdiag.exe、cmdkey.exe、cmdl32.exe、cmimageworker.exe、cmmon32.exe、cmproxyd.exe、cmstp.exe、cofire.exe、colorcpl.exe、comp.exe、compact.exe、CompatTelRunner.exe、CompMgmtLauncher.exe、CompPkgSrv.exe、ComputerDefaults.exe、conhost.exe、consent.exe、control.exe、convert.exe、convertvhd.exe、coredpussvr.exe、CredentialEnrollmentManager.exe、CredentialUIBroker.exe、credwiz.exe、cscript.exe、csrss.exe、ctfmon.exe、cttune.exe、cttunesvr.exe、curl.exe、CustomInstallExec.exe、CustomShellHost.exe、d3dconfig.exe、dasHost.exe、DataExchangeHost.exe、DataStoreCacheDumpTool.exe、DataUsageLiveTileTask.exe、dccw.exe、dcomcnfg.exe、ddodiag.exe、Defrag.exe、deploymentcsphelper.exe、desktopimgdownldr.exe、DeviceCensus.exe、DeviceCredentialDeployment.exe、DeviceEject.exe、DeviceEnroller.exe、DevicePairingWizard.exe、DeviceProperties.exe、DFDWiz.exe、dfrgui.exe、dialer.exe、directxdatabaseupdater.exe、diskpart.exe、diskperf.exe、diskraid.exe、DiskSnapshot.exe、Dism.exe、dispdiag.exe、DisplaySwitch.exe、djoin.exe、dllhost.exe、dllhst3g.exe、dmcertinst.exe、dmcfghost.exe、dmclient.exe、DmNotificationBroker.exe、DmOmaCpMo.exe、dnscacheugc.exe、doskey.exe、dpapimig.exe、DpiScaling.exe、dpnsvr.exe、driverquery.exe、drvinst.exe、DsmUserTask.exe、dsregcmd.exe、dstokenclean.exe、DTUHandler.exe、dusmtask.exe、dvdplay.exe、dwm.exe、DXCap.exe、DXCpl.exe、dxdiag.exe、dxgiadaptercache.exe、Dxpserver.exe、Eap3Host.exe、EaseOfAccessDialog.exe、easinvoker.exe、EASPolicyManagerBrokerHost.exe、EDPCleanup.exe、edpnotify.exe、EduPrintProv.exe、efsui.exe、EhStorAuthn.exe、EoAExperiences.exe、esentutl.exe、eudcedit.exe、eventcreate.exe、eventvwr.exe 、expand.exe、extrac32.exe、fc.exe、fhmanagew.exe、FileHistory.exe、find.exe、findstr.exe、finger.exe、fixmapi.exe、fltMC.exe、fodhelper.exe、Fondue.exe、fontdrvhost.exe、fontview.exe、forfiles.exe 、format.com、fsavailux.exe、FsIso.exe、fsquirt.exe、fsutil.exe、ftp.exe、fvenotify.exe、fveprompt.exe、GameBarPresenceWriter.exe、GamePanel.exe、GenValObj.exe、getmac.exe、gpresult.exe、gpscript.exe、gpupdate.exe、grpconv.exe、hcsdiag.exe、hdwwiz.exe、help.exe、hnsdiag.exe、hvax64.exe、hvc.exe、hvix64.exe、hvsievaluator.exe、iaStorAfsNative.exe、iaStorAfsService.exe、icacls.exe、IcsEntitlementHost.exe、icsunattend.exe、ie4uinit.exe、ie4ushowIE.exe、IESettingSync.exe、ieUnatt.exe、iexpress.exe、immersivetpmvscmgrsvr.exe、InfDefaultInstall.exe、InputSwitchToastHandler.exe、iotstartup.exe 、ipconfig.exe、iscsicli.exe、iscsicpl.exe、isoburn.exe、klist.exe、ksetup.exe、ktmutil.exe、label.exe、LanguageComponentsInstallerComHandler.exe、LaunchTM.exe、LaunchWinApp.exe、LegacyNetUXHost.exe、LicenseManagerShellext.exe、licensingdiag.exe、LicensingUI.exe、LocationNotificationWindows.exe、Locator.exe、LockAppHost.exe、LockScreenContentServer.exe、lodctr.exe、logagent.exe、logman.exe、logoff.exe、LogonUI.exe、lpkinstall.exe、lpksetup.exe、lpremove.exe、LsaIso.exe、lsass.exe、Magnify.exe、makecab.exe、manage-bde.exe、mavinject.exe、MbaeParserTask.exe、mblctr.exe、mcbuilder.exe、MDEServer.exe、MDMAgent.exe、MDMAppInstaller.exe、MdmDiagnosticsTool.exe、MdRes.exe、MdSched.exe、mfpmp.exe、Microsoft.Uev.CscUnpinTool.exe、Microsoft.Uev.SyncController.exe、MicrosoftEdgeBCHost.exe、MicrosoftEdgeCP.exe、MicrosoftEdgeDevTools.exe、MicrosoftEdgeSH.exe、mmc.exe、mmgaserver.exe、mobsync.exe、mode.com、more.com、mountvol.exe、MoUsoCoreWorker.exe、mpnotify.exe、MpSigStub.exe、MRT.exe、MSchedExe.exe、msconfig.exe、msdt.exe、msdtc.exe、msfeedssync.exe、msg.exe、mshta.exe、msiexec.exe 、msinfo32.exe、mspaint.exe、msra.exe、MsSpellCheckingHost.exe、mstsc.exe、mtstocom.exe、MuiUnattend.exe、MultiDigiMon.exe、MusNotification.exe、MusNotificationUx.exe、MusNotifyIcon.exe、Narrator.exe、nbtstat.exe、ndadmin.exe、NDKPing.exe、net.exe、net1.exe、netbtugc.exe、netcfg.exe、NetCfgNotifyObjectHost.exe、NetEvtFwdr.exe、NetHost.exe、netiougc.exe、Netplwiz.exe、netsh.exe、newdev.exe、NgcIso.exe、nltest.exe、nmbind.exe、nmscrub.exe、notepad.exe、nslookup.exe、ntoskrnl.exe、ntprint.exe 、nvspinfo.exe、odbcad32.exe、odbcconf.exe、ofdeploy.exe、omadmclient.exe、omadmprc.exe、openfiles.exe、OpenWith.exe、OptionalFeatures.exe、osk.exe、pacjsworker.exe、PackagedCWALauncher.exe、PackageInspector.exe、PasswordOnWakeSettingFlyout.exe、pcalua.exe、pcaui.exe、pcwrun.exe、perfmon.exe、phoneactivate.exe、PickerHost.exe、PinEnrollmentBroker.exe、PkgMgr.exe、PktMon.exe、plasrv.exe、PnPUnattend.exe、pnputil.exe、poqexec.exe、pospaymentsworker.exe、powercfg.exe、PresentationHost.exe、PresentationSettings.exe、prevhost.exe、print.exe、PrintBrmUi.exe、printfilterpipelinesvc.exe、PrintIsolationHost.exe、printui.exe、proquota.exe、provlaunch.exe、provtool.exe、ProximityUxHost.exe、prproc.exe、pwlauncher.exe、qappsrv.exe、qprocess.exe、query.exe、quser.exe、qwinsta.exe、rasautou.exe 、rasdial.exe、raserver.exe、rasphone.exe、rdpclip.exe、rdpinit.exe、rdpinput.exe、RdpSa.exe、RdpSaProxy.exe、RdpSaUacHelper.exe、rdpshell.exe、rdpsign.exe、rdrleakdiag.exe、ReAgentc.exe、recdisc.exe、recover.exe、RecoveryDrive.exe、refsutil.exe、reg.exe、regedt32.exe、regini.exe、Register-CimProvider.exe、regsvr32.exe、rekeywiz.exe、relog.exe、RelPost.exe、RemoteAppLifetimeManager.exe、RemotePosWorker.exe、repair-bde.exe、replace.exe、reset.exe、ResetEngine.exe、resmon.exe、RMActivate.exe 、RMActivate_isv.exe、RMActivate_ssp.exe、RMActivate_ssp_isv.exe、RmClient.exe、rmttpmvscmgrsvr.exe、Robocopy.exe、RpcPing.exe、rrinstaller.exe、rstrui.exe、runas.exe、rundll32.exe、runexehelper.exe、RunLegacyCPLElevated.exe、runonce.exe、RuntimeBroker.exe、rwinsta.exe、sc.exe、schtasks.exe、ScriptRunner.exe、sdbinst.exe、sdchange.exe、sdclt.exe、sdiagnhost.exe、SearchFilterHost.exe、SearchIndexer.exe、SearchProtocolHost.exe、SecEdit.exe、secinit.exe、securekernel.exe、SecurityHealthHost.exe、SecurityHealthService.exe、SecurityHealthSystray.exe、SensorDataService.exe、services.exe、sessionmsg.exe、sethc.exe、setspn.exe、SettingSyncHost.exe、setupcl.exe、setupugc.exe、setx.exe、sfc.exe、SgrmBroker.exe、SgrmLpac.exe、shrpubw.exe、shutdown.exe、sigverif.exe、SIHClient.exe、sihost.exe 、SlideToShutDown.exe、slui.exe、smartscreen.exe、smss.exe、SndVol.exe、SnippingTool.exe、snmptrap.exe、sort.exe、SpaceAgent.exe、spaceman.exe、SpatialAudioLicenseSrv.exe、Spectrum.exe、spoolsv.exe 、sppsvc.exe、srdelayed.exe、SrTasks.exe、stordiag.exe、subst.exe、svchost.exe、sxstrace.exe、SyncAppvPublishingServer.exe、SyncHost.exe、SysResetErr.exe、systeminfo.exe、SystemPropertiesAdvanced.exe、SystemPropertiesComputerName.exe、SystemPropertiesDataExecutionPrevention.exe、SystemPropertiesHardware.exe、SystemPropertiesPerformance.exe、SystemPropertiesProtection.exe、SystemPropertiesRemote.exe、systemreset.exe、SystemSettingsAdminFlows.exe、SystemSettingsBroker.exe、SystemSettingsRemoveDevice.exe、SystemUWPLauncher.exe、systray.exe、tabcal.exe、takeown.exe、TapiUnattend.exe、tar.exe、taskhostw.exe、taskkill.exe、tasklist.exe、Taskmgr.exe、tcblaunch.exe、tcmsetup.exe、ThumbnailExtractionHost.exe、TieringEngineService.exe、timeout.exe、TokenBrokerCookies.exe、TpmInit.exe、TpmTool.exe、tpmvscmgr.exe、tpmvscmgrsvr.exe、tracerpt.exe、tree.com、tscon.exe、tsdiscon.exe、tskill.exe、TSTheme.exe、TSWbPrxy.exe、ttdinject.exe、tttracer.exe、typeperf.exe、tzsync.exe、tzutil.exe、ucsvc.exe、UevAgentPolicyGenerator.exe、UevAppMonitor.exe、UevTemplateBaselineGenerator.exe、UevTemplateConfigItemGenerator.exe、UIMgrBroker.exe、unlodctr.exe、upfc.exe、UpgradeResultsUI.exe、upnpcont.exe、UserAccountBroker.exe、UserAccountControlSettings.exe、userinit.exe、UsoClient.exe、usocoreworker.exe、UtcDecoderHost.exe、Utilman.exe、VaultCmd.exe、vds.exe、vdsldr.exe、verclsid.exe、verifier.exe、verifiergui.exe、vfpctrl.exe、vmcompute.exe、VmComputeAgent.exe、vmconnect.exe、vmms.exe、vmplatformca.exe、vmsp.exe、vmwp.exe、VsGraphicsDesktopEngine.exe、VsGraphicsRemoteEngine.exe、vssadmin.exe、VSSVC.exe、vulkaninfo.exe、vulkaninfo-1-999-0-0-0.exe、w32tm.exe、WaaSMedicAgent.exe、waitfor.exe、WallpaperHost.exe、wbadmin.exe、wbengine.exe、wcsetupagent.exe、wecutil.exe、WerFault.exe、WerFaultSecure.exe、wermgr.exe、wevtutil.exe、wextract.exe、where.exe、whoami.exe、wiaacmgr.exe、wiawow64.exe、wifitask.exe、wimserv.exe、WinBioDataModelOOBE.exe、Windows.Media.BackgroundPlayback.exe、Windows.WARP.JITService.exe、WindowsActionDialog.exe、WindowsSandbox.exe、WindowsSandboxClient.exe、WindowsUpdateElevatedInstaller.exe、wininit.exe、winload.exe、winlogon.exe、winresume.exe、winrs.exe、winrshost.exe、WinRTNetMUAHostServer.exe、WinSAT.exe、winver.exe、wkspbroker.exe、wksprt.exe 、wlanext.exe、wlrmdr.exe、WMPDMC.exe、WorkFolders.exe、wowreg32.exe、WpcMon.exe、WpcTok.exe、WPDShextAutoplay.exe、wpnpinst.exe、wpr.exe、write.exe、wscadminui.exe、WSCollect.exe、wscript.exe、wsl.exe、wslconfig.exe、WSManHTTPConfig.exe、wsmprovhost.exe、wsqmcons.exe、WSReset.exe、wuapihost.exe 、wuauclt.exe、WUDFCompanionHost.exe、WUDFHost.exe、wusa.exe、WWAHost.exe、XblGameSaveTask.exe、xcopy.exe、xwizard.exe
C:\Windows\
bfsvc.exe、explorer.exe、HelpPane.exe、hh.exe、notepad.exe、regedit.exe、splwow64.exe、winhlp32.exe
C:\Windows\system32\Wbem\
mofcomp.exe、scrcons.exe、unsecapp.exe、wbemtest.exe、WinMgmt.exe、WMIADAP.exe、WmiApSrv.exe、WMIC.exe、WmiPrvSE.exe
C:\Windows\system32\WindowsPowerShell\v1.0\
powershell.exe
C:\Windows\system32\OpenSSH\
scp.exe、sftp.exe、sftp-server.exe、ssh.exe、ssh-add.exe、ssh-agent.exe、sshd.exe、ssh-keygen.exe、ssh-keyscan.exe、ssh-shellhost.exe

多くのコマンドはWindowsシステムにユニークな名前だが、いくつかのコマンドはLinuxでよく使われているコマンドと同じ名前であることがわかると思う。

WindowsコマンドとMSYS2コマンドの衝突

先ほどのリストのうち、特にMSYS2コマンドと衝突するのは次のコマンドだ。これらのコマンドを実行しようとしても、Windows側のコマンドのほうが優先的に実行されるのでとても使いにくい。

衝突するWindowsシステムコマンド
bash.exe、curl.exe、find.exe、ftp.exe、more.com、reset.exe、sort.exe、tar.exe、tree.com、whoami.exe

MSYS2でインストールされるコマンドを活用しようとしていると、上記コマンドはなにかと問題を引き起こす。前回取り上げた方法は簡易的にこれらを解決する方法だったのだが、MSYS2を本格的に使っていくと前回の方法では物足りなくなるはずだ。

Windowsと衝突を回避する抜本的な方法

前回取り上げた回避方法はどちらかというと折衷案的な方法だった。本格的にMSYS2を活用していくのであれば、もっとMSYS2を使いやすいようにする必要がある。いくつか方法が考えられるが、シンプルで強力なのは次の方法だ。

  1. MSYS2のパスを最優先に変更する。
  2. MSYS2コマンドと衝突するPowerShellエイリアスをすべて削除する


具体的には、次のような関数を作成する。この関数を実行すると、少なくともそのPowerShellはMSYS2のコマンドが優先的に実行されるようになる。

function msys2_mode {
        # MSYS2のコマンドパスを最優先に入れ替える
        $msyspath = "C:\msys64\usr\bin"
        $mingw64path = "C:\msys64\mingw64\bin"

        Set-Item Env:\Path $env:Path.Replace($mingw64path,"")
        Set-Item Env:\Path $env:Path.Replace($msyspath,"")

        Set-Item Env:\Path "$mingw64path;$env:Path"
        Set-Item Env:\Path "$msyspath;$env:Path"

        # MSYS2コマンドと重複するエイリアスを削除する
        Get-Alias cat > $null 2>&1 && Remove-Alias cat
        Get-Alias cp > $null 2>&1 && Remove-Alias cp
        Get-Alias ls > $null 2>&1 && Remove-Alias ls
        Get-Alias mv > $null 2>&1 && Remove-Alias mv
        Get-Alias rm > $null 2>&1 && Remove-Alias rm
        Get-Alias diff > $null 2>&1 && Remove-Alias -Force diff
        Get-Alias sort > $null 2>&1 && Remove-Alias -Force sort
        Get-Alias tee > $null 2>&1 && Remove-Alias -Force tee

        # ls系短縮コマンドを関数として作成
        function global:ls { C:\msys64\usr\bin\ls.exe --color $Args }
        function global:ll { C:\msys64\usr\bin\ls.exe --color $Args -l }
        function global:la { C:\msys64\usr\bin\ls.exe --color $Args -a }
}

しかしこれだと、MSYS2ではなくPowerShellのコマンドレットやWindowsシステム側のコマンドを実行したくなった場合に不便だ。このため、先ほどの関数で行ったことをすべて元に戻す関数を用意しておく。次のような関数だ。

function pwsh_mode {
        # MSYS2のコマンドパスを低優先へ入れ替える
        $msyspath = "C:\msys64\usr\bin"
        $mingw64path = "C:\msys64\mingw64\bin"

        Set-Item Env:Path $env:Path.Replace($msyspath,"")
        Set-Item Env:Path $env:Path.Replace($mingw64path,"")

        Set-Item Env:Path "$env:Path;$msyspath"
        Set-Item Env:Path "$env:Path;$mingw64path"

        # 作成した関数を削除
        Get-Item Function:ls > $null 2>&1 && Remove-Item Function:ls
        Get-Item Function:ll > $null 2>&1 && Remove-Item Function:ll
        Get-Item Function:la > $null 2>&1 && Remove-Item Function:la

        # 削除したエイリアスを元に戻す
        Get-Alias cat > $null 2>&1 || Set-Alias -Force -Name cat -Value Get-Content
        Get-Alias cp > $null 2>&1 || Set-Alias -Force -Name cp -Value Copy-Item
        Get-Alias ls > $null 2>&1 || Set-Alias -Force -Name ls -Value Get-ChildItem
        Get-Alias mv > $null 2>&1 || Set-Alias -Force -Name mv -Value Move-Item
        Get-Alias rm > $null 2>&1 || Set-Alias -Force -Name rm -Value Remove-Item
        Get-Alias diff > $null 2>&1 || Set-Alias -Force -Name diff -Value Compare-Object
        Get-Alias sort > $null 2>&1 || Set-Alias -Force -Name sort -Value Sort-Object -Option ReadOnly
        Get-Alias tee > $null 2>&1 || Set-Alias -Force -Name tee -Value Tee-Object -Option ReadOnly
}

こうしておけば、PowerShellを使っている状態でも操作モードを切り替えて操作することができる。これはなかなか強力で便利な方法だ。前回の懸念事項だった削除できないエイリアスについても、こちらでは元に戻せるという前提になっているので強制的に削除しており、より徹底したMSYS2の使用が可能だ。

処理の内容を説明すると長くなってしまうので、今回はここまでで切り上げる。次回、この関数を設定ファイルに追加/利用する方法や、設定内容そのものについて説明する。問題が発生するケースなども取り上げ、こうした関数による切り替えが効果的である理由についても解説しよう。