Blank?=False

ゆるゆる仕事したいフリーランスエンジニアの記事

LinuxのコマンドはMacOSXでそのまま動くとは限らない

f:id:stonebeach-dakar:20170104183805j:plain

LinuxのコマンドをMacOSXでやってみたところ、そのままでは動かない、といことがありました。
LinuxのコマンドがなぜMacOSXで動かないのか?をちょっと調べてみました。

やりたかったこと

特定の拡張子のファイルを、指定したフォルダに移動する、ということがやりたかったのです。
テキストファイルをfooディレクトリに移動する、という例で説明すると、下のようなコマンドになります。

$find . -name "*.txt" | xargs -i mv {} ~/foo


このコマンドは以下の記事を参考にさせていただきました。
hiropo.co.uk


ためしにCentOSでやってみたらちゃんと出来たので、MacOSXでもできるかな、と思ったんです。

MacOSXだと動かなかった

これを、MacOSXでやろうとしたところ、以下のようなエラーが発生しました。

$find . -name "*.txt" | xargs -i mv {}  ~/foo
xargs: illegal option -- i
usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]
             [-L number] [-n number [-x]] [-P maxprocs] [-s size]
             [utility [argument ...]]


xargsのコマンドに-iというオプションはないよ!と出て、オプションリストには大文字の-Iとありますので、 次に大文字の-Iをオプション指定すると、また別のエラーが出ます。

$find . -name "*.txt" | xargs -I mv {}  ~/foo
xargs: {}: No such file or directory


今度は、{}はファイルでもないしディレクトリでもないよ、というエラーです。
ここで、OSXだと動かないコマンド、ということに気づきました。

なぜ動かなかったのか

結論から言えば、MacOSXLinuxでは、xargsコマンドのオプションが多少異なっていた、というのが原因でした。

Linuxのxargsコマンドの展開オプションは、-iと-Iの2つですが、MacOSXの場合は-Iと-Jでした。
Linuxの-IオプションがMacOSXの-Jオプションと似たような動きとなり、 Linuxの-iオプションは展開文字を指定しなければが{}となりますが、MacOSXの-Iオプションの場合、回数制限付きの展開オプションとなります。
MacOSXの-Iオプションは挙動が少しよくわからないところがあります…。

今回、Linuxの-iコマンドに相当するものはMacOSXにはないので、-Iオプションに相当する-Jオプションと展開文字の指定が必要だった、というわけです。

LinuxMacOSXは実装が違う

Linuxのコマンドは、GNU版、そしてMacOSXのコマンドはFreeBSD版です。
同じようなコマンドに見えても、開発元が違うんですね。

開発元を確認する正しい方法がわからなかったので、manコマンドでオンラインマニュアルを見て確認しました。
MacOSX

$man find
FIND(1)                   BSD General Commands Manual                  FIND(1)

NAME
     find -- walk a file hierarchy

SYNOPSIS
     find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
     find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]

DESCRIPTION
     The find utility recursively descends the directory tree for each path listed, evaluating an expression (composed of the ``primaries'' and ``operands'' listed below) in terms of each
     file in the tree.


CentOS7

$man find
General Commands Manual                                                                                    FIND(1)



NAME
       find - search for files in a directory hierarchy

SYNOPSIS
       find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]

DESCRIPTION
       This  manual page documents the GNU version of find.  GNU find searches the directory tree rooted at each given file name by evaluating the given expression from left to right, according to the rules
       of precedence (see section OPERATORS), until the outcome is known (the left hand side is false for and operations, true for or), at which point find moves on to the next file name.



なぜMacOSXFreeBSD版になっているのかというと、MacOSXの元になったNEXTSTEPBSDの子孫だということ、そしてFreeBSD5の環境を実装していることによるものです。

【参考元】
UNIX - Wikipedia
プログラマーを引き付けるMac OS Xの魅力 − @IT


BSDLinux、何が違うの?同じUnixでしょ?と疑問を持たれる方もおられるかもしれません。
これは昔、私もそう思ったことがあります。

そもそも、Unixというのは今は特定のOSではなく、かって存在したUnixOSの設計哲学などを継承したOSを指す言葉となっています。
なので、設計哲学に準拠されていればUnix系OSと呼ばれることになっており、カーネルの実装が全く異なっていても、Unixと言われるんですね。
こういったことになっているので、似たような操作感でも微妙にコマンドの動きが異なる、ということはよくあることです。

こういうOSの歴史を勉強するのも結構面白いので、もし興味を持たれたら色々調べてみると良いと思います。
意外と、このOSはこういう歴史があるからこういう仕組みになっている、ということが理解しやすくなり、 よりOSを有効活用するアプリケーションが作れるようになります。たぶん。


というわけで、Linuxで動くコマンドがMacOSXだと動かない、というのは普通に有ることです。
MacOSXMacOSXのコマンドでやらなきゃな、ということに気付かさた日でした。
機会があればFreeBSDもさわってみようかな。

もし、Unixをより知りたいと思った方は以下の書籍がおすすめです。

UNIXという考え方―その設計思想と哲学

UNIXという考え方―その設計思想と哲学