WindowsでLinux

「WindowsでLinuxコマンドを使う」場合、仮想化技術が普及する前であれば「Cygwin」のようなソフトウエアを使うのが一般的だったように思う。仮想化技術が登場した後は、仮想環境にLinuxをインストールして利用できるようになった。そして双方の取り組みの後継として、Cygwinには「MSYS2」が、仮想化技術を使った方法の発展系として「WSL2」が存在するというイメージだ。

WSL1/WSL2は、いずれもMicrosoftが提供する標準機能だ。これらの機能が登場するまで、WindowsでLinuxコマンドを標準機能として利用できるようになるとは思わなかった。WSL1やWSL2がWindowsとLinuxに与えた影響は大きい。PCのOSとしてWindowsは圧倒的なシェアを持っている。そのOSでLinuxのコマンドが利用できるということは、世界中の大半のPCでLinuxコマンドが利用できる状況にあるということだ。

これまで、UNIX系コマンドの互換性という面では対応の弱さが否めなかったWindowsだが、今ではLinuxコマンドを利用するならWindowsがあればよいと言えるまでの状況になっている。ここ数年の変化は相当に大きい。

MacでLinux

Windowsのシェアと比べると、Macのシェアは小さい。StatCounter GlobalStatsのデータによれば、2021年11月のPCにおけるWindowsのシェアは74%、Macのシェアは16%ほどだ。細かいシェアの変動はあるものの、年間で見るとほぼこれくらいの割合で横ばいの推移を見せている。

WindowsはLinuxとは生まれた経緯が異なっており、もともとシステムコールに互換性がない。もちろん提供されているベースコマンドにも互換性はなく、文化的にも仕様的にも大きな違いがある。

一方、MacはUNIX系のソフトウエアを取り込みながらOSを開発しており、POSIXに準拠するところが大きい。ユーザーランドはFreeBSDからコマンドを移植し、POSIXに準拠したシステムコールを提供し、また、FreeBSD特有のシステムコールなども提供している。そもそもがUNIX系のソフトウエアであり、使い方はLinuxに近い。

このため、MacはWSL2やMSYS2といった技術の必要性が低い。Macに最初から備わっている機能がLinuxの提供しているものとよく似ており、別途ソフトウエアをインストールしたり、機能をセットアップしたりすることなく利用できるからだ。

Macで提供されているコマンド

Macで提供されているコマンドを調べてみよう。macOS Montereyに標準で含まれているコマンドと、さらにCommand Line Tools for Xcodeをインストールした状態のコマンドは、次のような感じになっている。

パス コマンド
/bin/ [, bash, cat, chmod, cp, csh, dash, date, dd, df, echo, ed, expr, hostname, kill, ksh, launchctl, link, ln, ls, mkdir, mv, pax, ps, pwd, rm, rmdir, sh, sleep, stty, sync, tcsh, test, unlink, wait4path, zsh
/sbin/ apfs_hfs_convert, apfs_unlockfv, disklabel, dmesg, dynamic_pager, emond, fibreconfig, fsck, fsck_apfs, fsck_cs, fsck_exfat, fsck_hfs, fsck_msdos, fsck_udf, fstyp, fstyp_hfs, fstyp_msdos, fstyp_ntfs, fstyp_udf, halt, ifconfig, kextload, kextunload, launchd, md5, mknod, mount, mount_9p, mount_acfs, mount_afp, mount_apfs, mount_cd9660, mount_cddafs, mount_devfs, mount_exfat, mount_fdesc, mount_ftp, mount_hfs, mount_lifs, mount_msdos, mount_nfs, mount_ntfs, mount_smbfs, mount_tmpfs, mount_udf, mount_webdav, mpioutil, newfs_apfs, newfs_exfat, newfs_hfs, newfs_msdos, newfs_udf, nfsd, nfsiod, nologin, pfctl, ping, ping6, quotacheck, reboot, route, shutdown, umount
/usr/bin/ 2to3-, 2to3-2.7, AssetCacheLocatorUtil, AssetCacheManagerUtil, AssetCacheTetheratorUtil, DeRez, GetFileInfo, IOAccelMemory, IOMFB_FDR_Loader, ResMerger, Rez, SafeEjectGPU, SetFile, SplitForks, a2p, aa, actool, addftinfo, aea, afclip, afconvert, afhash, afida, afinfo, afktool, afmtodit, afplay, afscexpand, agentxtrap, agvtool, alias, app-sso, applesingle, appletviewer, apply, apropos, apt, ar, arch, as, asa, assetutil, at, atos, atq, atrm, atsutil, automationmodetool, automator, auval, auvaltool, avbdiagnose, avbutil, avconvert, avmediainfo, avmetareadwrite, awk, banner, base64, basename, bashbug, batch, bc, bg, biff, binhex, binhex.pl, binhex5.18.pl, binhex5.30.pl, bioutil, bison, bitesize.d, bputil, brctl, bsdtar, bspatch, bundle, bundler, bunzip2, bzcat, bzcmp, bzdiff, bzegrep, bzfgrep, bzgrep, bzip2, bzip2recover, bzless, bzmore, c++, c++filt, c2ph, c89, c99, caffeinate, cal, calendar, cancel, cap_mkdb, captoinfo, cc, cd, certtool, checknr, chflags, chfn, chgrp, chpass, chsh, cksum, clang, clang++, clangd, clear, cmp, cmpdylib, codecctl, codesign, codesign_allocate, col, colcrt, colldef, colrm, column, comm, command, compress, compression_tool, config_data, config_data5.30, corelist, corelist5.18, corelist5.30, cpan, cpan2dist, cpan5.18, cpan5.30, cpanp, cpanp-run-perl, cpio, cpp, cpu_profiler.d, cpuctl, cpuwalk.d, crc32, crc325.18, crc325.30, creatbyproc.d, crlrefresh, crontab, csplit, csreq, csrutil, ctags, ctf_insert, cu, cups-config, cupstestppd, curl, curl-config, cut, cvaffinity, cvcp, cvmkdir, cvmkfile, dappprof, dapptrace, db_archive, db_checkpoint, db_codegen, db_deadlock, db_dump, db_hotbackup, db_load, db_printlog, db_recover, db_stat, db_upgrade, db_verify, dbicadmin, dbicadmin5.18, dbicadmin5.30, dbilogstrip, dbilogstrip5.18, dbilogstrip5.30, dbiprof, dbiprof5.18, dbiprof5.30, dbiproxy, dbiproxy5.18, dbiproxy5.30, dc, debinhex.pl, debinhex5.18.pl, debinhex5.30.pl, defaults, delv, demandoc, desdp, diagnose-fu, diff, diff3, diffstat, dig, dirname, dispqlen.d, ditto, dmc, dns-sd, drutil, dscacheutil, dscl, dserr, dsexport, dsimport, dsmemberutil, dsymutil, dtruss, du, dwarfdump, dyld_info, easy_install, easy_install-2.7, egrep, enc2xs, enc2xs5.18, enc2xs5.30, encguess, encode_keychange, env, eqn, erb, errinfo, ex, execsnoop, expand, expect, extcheck, eyapp, eyapp5.18, eyapp5.30, false, fc, fddist, fdesetup, fg, fgrep, file, filebyproc.d, fileproviderctl, filtercalltree, find, find2perl, findrule, findrule5.18, findrule5.30, finger, fixproc, flex, flex++, fmt, fold, fontrestore, footprint, format-sql, format-sql5.18, from, fs_usage, funzip, fuser, fwkdp, fwkpfv, g++, gatherheaderdoc, gcc, gcore, gcov, gdiffmk, gem, gen_bridge_metadata, gencat, genstrings, getconf, getopt, getopts, git, git-receive-pack, git-shell, git-upload-archive, git-upload-pack, gm4, gnumake, gperf, grep, grn, grodvi, groff, groffer, grog, grolbp, grolj4, grops, grotty, groups, gunzip, gzcat, gzexe, gzip, h2ph, h2ph5.18, h2ph5.30, h2xs, h2xs5.18, h2xs5.30, hash, hdid, hdiutil, hdxml2manxml, head, headerdoc2html, heap, hexdump, hidutil, hiutil, host, hostinfo, hotspot.d, hpftodit, hpmdiagnose, htmltree, htmltree5.18, htmltree5.30, ibtool, iconutil, iconv, ictool, id, idle, idle2.7, idlj, imptrace, indent, indxbib, info, infocmp, infokey, infotocap, install, install-info, install_name_tool, instmodsh, instmodsh5.18, instmodsh5.30, iofile.d, iofileb.d, iopattern, iopending, iosnoop, iotop, ip2cc, ip2cc5.18, ip2cc5.30, ipcount, ipcount5.18, ipcount5.30, ipcrm, ipcs, ippeveprinter, ippfind, ipptool, iptab, iptab5.18, iptab5.30, irb, jar, jarsigner, java, javac, javadoc, javah, javap, javapackager, javaws, jcmd, jconsole, jcontrol, jdb, jdeps, jhat, jhsdb, jimage, jinfo, jjs, jlink, jmap, jmc, jobs, join, jot, jpackage, jps, jrunscript, jsadebugd, jshell, json_pp, json_pp5.18, json_pp5.30, json_xs, json_xs5.30, jstack, jstat, jstatd, jvisualvm, kcc, kdestroy, kextutil, keytool, kgetcred, kill.d, killall, kinit, klist, kmutil, kpasswd, krb5-config, kswitch, ktrace, lam, last, lastcomm, lastwords, latency, layerutil, ld, ldapadd, ldapcompare, ldapdelete, ldapexop, ldapmodify, ldapmodrdn, ldappasswd, ldapsearch, ldapurl, ldapwhoami, leaks, leave, less, lessecho, lex, libnetcfg, libnetcfg5.18, libnetcfg5.30, libtool, lipo, lkbib, lldb, llvm-g++, llvm-gcc, loads.d, locale, localedef, locate, lockstat, log, logger, login, logname, look, lookbib, lorder, lp, lpoptions, lpq, lpr, lprm, lpstat, lsappinfo, lsbom, lskq, lsm, lsmp, lsvfs, lwp-download, lwp-download5.18, lwp-download5.30, lwp-dump, lwp-dump5.18, lwp-dump5.30, lwp-mirror, lwp-mirror5.18, lwp-mirror5.30, lwp-request, lwp-request5.18, lwp-request5.30, m4, macbinary, macerror, macerror5.18, macerror5.30, machine, mail, mailq, mailx, make, makeinfo, malloc_history, man, mandoc, mandoc_soelim, manpath, mcxquery, mcxrefresh, mddiagnose, mdfind, mdimport, mdls, mdutil, memory_pressure, mesg, mg, mib2c, mib2c-update, mig, mkbom, mkfifo, mklocale, mktemp, mmroff, mnthome, moo-outdated, moo-outdated5.18, moose-outdated, moose-outdated5.18, moose-outdated5.30, more, mp2bug, msgs, nano, native2ascii, nbdst, nc, ncal, ncctl, ncdestroy, ncinit, nclist, ncurses5.4-config, neqn, net-server, net-server5.18, net-server5.30, net-snmp-cert, net-snmp-config, net-snmp-create-v3-user, nettop, networkQuality, newaliases, newgrp, newproc.d, nfsstat, nice, nl, nm, nmedit, nohup, notifyutil, nroff, nscurl, nslookup, nsupdate, objdump, ocspcheck, od, odutil, open, opendiff, opensnoop, openssl, orbd, osacompile, osadecompile, osalang, osascript, otool, pack200, package-stash-conflicts, package-stash-conflicts5.18, package-stash-conflicts5.30, pagesize, pagestuff, par.pl, par5.30.pl, parl, parl5.30, parldyn, parldyn5.30, passwd, paste, patch, pathchk, pathopens.d, pbcopy, pbpaste, pcap-config, pcsctest, perl, perl5.18, perl5.30, perlbug, perlbug5.18, perlbug5.30, perldoc, perldoc5.18, perldoc5.30, perlivp, perlivp5.18, perlivp5.30, perlthanks, perlthanks5.18, perlthanks5.30, pfbtops, pgrep, pic, pico, piconv, piconv5.18, piconv5.30, pidpersec.d, pip3, pkgbuild, pkill, pl, pl2pm, pl2pm5.18, pl2pm5.30, plockstat, pluginkit, plutil, pmset, pod2html, pod2html5.18, pod2html5.30, pod2latex, pod2man, pod2man5.18, pod2man5.30, pod2readme, pod2readme5.18, pod2readme5.30, pod2text, pod2text5.18, pod2text5.30, pod2usage, pod2usage5.18, pod2usage5.30, podchecker, podchecker5.18, podchecker5.30, podselect, podselect5.18, podselect5.30, policytool, post-grohtml, power_report.sh, powermetrics, pp, pp5.30, ppdc, ppdhtml, ppdi, ppdmerge, ppdpo, pr, pre-grohtml, priclass.d, pridist.d, printenv, printf, procsystime, productbuild, productsign, profiles, prove, prove5.18, prove5.30, psed, psm, pstopdf, pstruct, ptar, ptar5.18, ptar5.30, ptardiff, ptardiff5.18, ptardiff5.30, ptargrep, ptargrep5.18, ptargrep5.30, pwhich, pwhich5.18, pwpolicy, pydoc, pydoc2.7, python, python-config, python2, python2.7, python2.7-config, python3, pythonw, pythonw2.7, qlmanage, quota, rails, rake, ranlib, rdoc, read, readlink, refer, renice, reset, resolveLinks, rev, ri, rmic, rmid, rmiregistry, rpcgen, rs, rsync, ruby, rview, rvim, rwbypid.d, rwbytype.d, rwsnoop, s2p, safaridriver, sample, sampleproc, sandbox-exec, say, sc_usage, scandeps.pl, scandeps5.18.pl, scandeps5.30.pl, schemagen, scp, screen, script, sdef, sdiff, sdp, sdx, security, sed, seeksize.d, segedit, seq, serialver, servertool, setregion, setuids.d, sfltool, sftp, shar, shasum, shasum5.18, shasum5.30, shlock, shortcuts, showmount, sigdist.d, sips, size, slogin, smbutil, smtpd.py, smtpd2.7.py, snfsdefrag, snmp-bridge-mib, snmpbulkget, snmpbulkwalk, snmpconf, snmpdelta, snmpdf, snmpget, snmpgetnext, snmpinform, snmpnetstat, snmpset, snmpstatus, snmptable, snmptest, snmptranslate, snmptrap, snmpusm, snmpvacm, snmpwalk, sntp, soelim, sort, sourcekit-lsp, spfd, spfd5.18, spfd5.30, spfquery, spfquery5.18, spfquery5.30, splain, splain5.18, splain5.30, split, sqlite3, ssh, ssh-add, ssh-agent, ssh-copy-id, ssh-keygen, ssh-keyscan, stapler, stat, stringdups, strings, strip, stty.pl, stty5.18.pl, su, sudo, sum, sw_vers, swcutil, swift, swiftc, symbols, symbolscache, syscallbypid.d, syscallbyproc.d, syscallbysysc.d, syscapturediags, sysdiagnose, syslog, systemextensionsctl, tab2space, tabs, tail, tailspin, talk, tar, taskinfo, tbl, tbtdiagnose, tccutil, tclsh, tclsh8.5, tee, test-yaml, test-yaml5.30, texi2dvi, texi2pdf, texindex, textutil, tfmtodit, tftp, thermal, tic, tidy, tidy_changelog, tidy_changelog5.30, tiff2icns, tiffutil, time, timer_analyser.d, timerfires, timesyncanalyse, tkcon, tkmib, tkpp, tkpp5.30, tmdiagnose, tmutil, tnameserv, toe, top, tops, topsyscall, topsysproc, touch, tput, tr, trace, traptoemail, treereg, treereg5.18, treereg5.30, trimforce, troff, true, trustcachectl, tset, tsort, tty, type, ul, ulimit, umask, umtool, unalias, uname, uncompress, unexpand, unifdef, unifdefall, uniq, units, unpack200, unvis, unzip, unzipsfx, update_dyld_shared_cache, update_mcdp29xx, uptime, usbcfwflasher, users, uttype, uucp, uudecode, uuencode, uuidgen, uulog, uuname, uupick, uustat, uuto, uux, vi, view, vim, vimdiff, vimtutor, vis, vm_stat, vmmap, vtool, w, wait, wall, wc, wdutil, what, whatis, whereis, which, who, whoami, whois, wish, wish8.5, write, wsgen, wsimport, xar, xargs, xattr, xcode-select, xcodebuild, xcrun, xcscontrol, xcsdiagnose, xctrace, xed, xgettext.pl, xgettext5.18.pl, xgettext5.30.pl, xip, xjc, xml2-config, xml2man, xmlcatalog, xmllint, xpath, xpath5.18, xpath5.30, xslt-config, xsltproc, xsubpp, xsubpp5.18, xsubpp5.30, xxd, yaa, yacc, yamlpp-events, yamlpp-events5.30, yamlpp-highlight, yamlpp-highlight5.30, yamlpp-load, yamlpp-load-dump, yamlpp-load-dump5.30, yamlpp-load5.30, yamlpp-parse-emit, yamlpp-parse-emit5.30, yapp, yapp5.30, yes, zcat, zcmp, zdiff, zegrep, zfgrep, zforce, zgrep, zip, zipcloak, zipdetails, zipdetails5.18, zipdetails5.30, zipgrep, zipinfo, zipnote, zipsplit, zless, zmore, znew, zprint
/usr/sbin/ BTLEServer, BTLEServerAgent, BlueTool, BootCacheControl, DevToolsSecurity, DirectoryService, KernelEventAgent, PasswordService, WirelessRadioManagerd, ab, ac, accton, amt, apachectl, applecamerad, appleh13camerad, appsleepd, arp, aslmanager, asr, audit, auditd, auditreduce, authserver, automount, avbdeviced, bless, bluetoothd, bnepd, cfprefsd, chat, checkgid, chown, chroot, ckksctl, coreaudiod, createhomedir, cron, cupsaccept, cupsctl, cupsd, cupsdisable, cupsenable, cupsfilter, cupsreject, cvadmin, cvdb, cvdbset, cvfsck, cvfsdb, cvfsid, cvgather, cvlabel, cvmkfs, cvupdatefs, cvversions, dbmmanage, ddns-confgen, dev_mkdb, disktool, diskutil, distnoted, dnctl, dot_clean, dsconfigad, dsconfigldap, dseditgroup, dsenableroot, dtrace, edquota, envvars, envvars-std, fcgistarter, fdisk, filecoordinationd, firmwarepasswd, gpt, graphicssession, gssd, hdik, htcacheclean, htdbm, htdigest, htpasswd, httpd, httpd-wrapper, httxt2dbm, iRATBW.mlmodelc, installer, ioalloccount, ioclasscount, ioreg, iostat, ipconfig, kadmin, kadmin.local, kcditto, kdcsetup, kextcache, kextfind, kextlibs, kextstat, klist_cdhashes, krbservicesetup, ktutil, languagesetup, localemanager, logresolve, lpadmin, lpc, lpinfo, lpmove, lsof, mDNSResponder, mDNSResponderHelper, mkextunpack, mkfile, mkpassdb, mtree, ndp, netbiosd, netstat, networksetup, newsyslog, nfs4mapid, nlcontrol, notifyd, nvram, ocspd, otctl, pdisk, periodic, pkgutil, postalias, postcat, postconf, postdrop, postfix, postkick, postlock, postlog, postmap, postmulti, postqueue, postsuper, pppd, praudit, purge, pwd_mkdb, quotaoff, quotaon, racoon, rarpd, repairHomePermissions, repquota, rotatelogs, rpc.lockd, rpc.statd, rpcbind, rpcinfo, rtadvd, sa, sc_auth, screencapture, scselect, scutil, securityd, sendmail, serverinfo, setkey, setquota, sharing, skywalkctl, slapacl, slapadd, slapauth, slapcat, slapconfig, slapdn, slapindex, slappasswd, slapschema, slaptest, smbd, smbdiagnose, sndiskmove, snmpd, snmptrapd, snquota, sntpd, softwareupdate, spctl, spindump, spray, sshd, sso_util, sysadminctl, sysctl, syslogd, system_profiler, systemkeychain, systemsetup, systemsoundserverd, systemstats, taskpolicy, tcpdump, tpctl, traceroute, traceroute6, tsig-keygen, uasysdiagnose, universalaccessd, unsetpassword, usernoted, uuchk, uucico, uuconv, uusched, uuxqt, vifs, vipw, visudo, vpnd, vsdbutil, weakpass_edit, wfsctl, xartutil, xsanctl, xscertadmin, zdump, zic

単純に集計すると、次のように合計で1350個くらいはコマンドが収容されていることになる。

REGNACROXE ~% ls /bin /sbin /usr/bin /usr/sbin | wc -l
    1362
REGNACROXE ~% 

提供されるコマンドはOSごとに多少異なるので名前が違うものもあると思うが、普段Linuxを使っている方は提供されているコマンドをチェックしてみてほしい。いつも使っているコマンドが結構含まれていることがわかるはずだ。これだけでも結構Linux的な使い方ができる。

ネイティブでネイティブ速度に動くMacのコマンド

MSYS2とWSL2の仕組みと特徴を思い出してみていただきたい。まず、MSYS2はLinuxコマンドをWindowsカーネルでネイティブに動作するようにしたものだった。ただし、Windowsカーネルの提供しているシステムコールはPOSIX互換ではない。つまり、WindowsではLinuxのコマンドやライブラリはそのままでは利用できない。

MSYS2はLinuxのコマンドをそれぞれWindows APIなどを使うかたちで移植するのではなく、一枚レイヤを挟んでLinuxシステムコールや関数をWindowsの関数を使うように置き換える技術で実現するという方法を使っていた。この方法であれば、オリジナルのLinuxコマンドはそのままに、Windowsでネイティブに動作するバイナリを生成することができる。かなり理想的な状況なわけだが、一点、実行速度がとても遅いという問題があった。

一方、WSL2はHyper-Vという仮想化技術を使ってLinuxカーネルそのものを動作させるものだ。そのため、Linuxで動作するコマンドであれば基本的にWSL2でも利用することができる。さらに、WSL2は実行速度が高速であるという特徴があった。結構驚くほどの速度で動作する。仮想環境内で動作しているのだが、MicrosoftはWSL2がWindowsとシームレスに統合した動作を見せるように工夫を加えており、それなりにネイティブに動作しているようにも使うことができる。かなりよくできた技術だ。ただし、一部のコマンドはWindowsからはうまく利用できないほか、Linuxカーネルがファイルシステムキャッシュなどにメモリを確保すると大量のメモリがWindowsから持ていかれるという問題があることを指摘した。

このように、MSYS2とWSL2は利用している技術が根本的に異なっており、その特性も大きく違っている。それぞれを適材適所で使うというのがこの技術の活用方法ということになる。

一方、Macは状況が異なっている。MacのカーネルはそもそもPOSIXのシステムコールを理解するので、MSYS2のようにわざわざ変換のレイヤを挟む必要がない。Linuxコマンドはコンパイルすれば、またはソースコードやビルド方法にいくらかの変更を加えれば、ビルドして利用することができる。Macのカーネルが直接解釈して実行することができる。

そのため、MSYS2のように実行速度が100倍、みたいな遅さになることがない。また、Macのネイティブコマンドとしてそのまま実行されるので、実行速度も高速だ。さらに、仮想環境で動作しているわけではないので、WSL2のようにページャがうまく使えないとか、そういった環境をまたぐことで発生してしまう問題というものもない。MSYS2とWSL2の双方の利点がそのまま使える、それがMacということになる。

パッケージ管理システム

MSYS2にはpacman、WSL2には(デフォルトのUbuntuをインストールした場合には)aptというパッケージ管理システムがある。デフォルトでインストールされていないコマンドを使おうと思ったら、パッケージ管理システムを使ってソフトウエアを検索し、対象となるソフトウエアをインストールして利用することができる。Linuxでは標準的な使い方であり、とても重要な機能だ。最近はWindowsもようやくWingetと呼ばれる似たような機能を実現するようになった。WindowsもWingetの登場でソフトウエア管理がとても簡単に(特にアドバンスドユーザーにとっては)なってきたのだ。

Macにはデフォルトではそうした機能はない。ただし、サードパーティー製となるが、Macでも似たようなパッケージ管理システムを利用することができる。本稿執筆時点では「Homebrew」が代表的ではないかと思う。

  • Homebrewでインストールしたneofetchを実行 - macOS Monterey

    Homebrewでインストールしたneofetchを実行 - macOS Monterey

Homebrewの使い方はUbuntuの「apt」ともよく似ているので、Linuxを使った経験があれば、ほとんど迷うことなく利用できるはずだ。この点に関してもMacは問題が少ない。

MacとWindowsはLinuxコマンドのプラットフォーム

Macでデフォルト提供されているコマンドは正確には全てがLinuxでよく使われているコマンドということではなく、特にベースコマンドにはFreeBSD由来のコマンドが使われている。このため、Linuxのコマンドと比べるとオプションや動作などが多少異なる。これはUNIX系のOSにはよくあることで、同じ名前でコマンドでもオプションや挙動が違っている。POSIXで規定されていないところはOSごとに異なっていることが多い。

そのため、完全にLinuxと同じように使えるわけではないのだが、Homebrewを使って後からパッケージをインストールすれば、ほぼLinuxと同じような使い方もできる。そうなると、MacをLinuxのプラットフォームとして使うというのは、結構有力な選択肢となってくる。

最初に取り上げた市場シェアについてもう一度見てみよう。StatCounter GlobalStatsのデータによれば、2021年11月のパソコンにおけるWindowsのシェアは74%、Macのシェアは16%ほどだ。両方合わせると、PCのシェアの90%ほどはWindowsとMacで占められている、ということになる。そして、この2つのOSはLinuxコマンドが実行できる状況になっている。単純に考えると世界中のPCの9割でLinuxコマンドが利用しやすい状況にあるわけだ(Windowsの古いバージョンは状況が違うので実際の割合はもっと下がる)。

これは結構大きなことだ。これまではLinuxのコマンドはLinuxで使うものだと考えられてきたが、現在ではWindowsでもMacでも利用できる。Linuxコマンドのスキルを身に付けていれば、WindowsでもMacでもそのスキルと活かすことができるのだ。Linuxコマンドを使いこなすスキルが、プラットフォームを超えて利用できるスキルとして価値のあるものになりつつある。