GNUとBSDの挙動の違いメモ
パイプ等と合わせて入力を引数としてコマンド実行するxargs
ですが、GNU/BSDで違いが大きいようです。
入力がからの時に実行するか
$ echo world! | xargs echo hello # echo hello world! と等価
ではパイプによる入力がからの時どうなるのか
BSD系では
$ echo | xargs echo hello
$ echo $?
0
何も表示されず、ステータスコードも正常です。
一方のGNU系は
$ echo | xargs echo hello
hello
$ echo $?
0
パイプ以下のecho
は実行されました。
ここで例えばディレクトリにある特定ファイルを確認したい時、
$ find ./ -maxdepth 2 -name "*hogehoge*" | xargs basename
こんなことをするとして、
BSD系では、
$ find ./ -maxdepth 2 -name "*hogehoge*" | xargs basename
$ echo $?
0
何も見つからない時、何も表示せず、正常終了します。
GNU系では、
$ find ./ -maxdepth 2 -name "*hogehoge*" | xargs basename
basename: missing operand
Try `basename --help' for more information.
$ echo $?
123
引数なしでbasename
は一回実行されてエラーを起こします。
--no-run-if-empty, -r オプション
GNU系には上記のオプションがあり、BSD系に挙動を合わせることができます。一部のBSD系は-r
オプションを擬似オプション(何も動作しないオプション)として導入しています。