Linuxで同じバージョンの「インストール」が正しく機能しているため、入力をリダイレクトするとOS X「インストール」エラーが発生するのはなぜですか?

Linuxで同じバージョンの「インストール」が正しく機能しているため、入力をリダイレクトするとOS X「インストール」エラーが発生するのはなぜですか?

installコマンドを使用して、あらかじめ入力されたコンテンツ(たとえば、pwd単一のコマンド)を含む新しい実行可能ファイルを作成したいと思います。

だから延長しました。これ新しい空の実行可能ファイル生成の例:

install -b -m 755 /dev/null newfile

以下を入力してください:

install -m755 <(echo pwd) newfile

または:

echo pwd | install -m755 /dev/stdin newfile

newfileコンテンツを含む新しい実行可能ファイルを作成したいですpwd

Linuxではうまく機能しますが、OS Xでは次のエラーで失敗します。

  • BSD install/usr/bin/install

    インストール: /dev/fd/63: 不適切なファイルの種類または形式

  • グヌinstall/usr/local/opt/coreutils/libexec/gnubin/install

    インストール:/dev/fd/63ファイルのコピー時に置き換えられたため、ファイルをスキップ

これがUnixでは動作しませんが、Linuxでは動作するのはなぜですか?何か抜けましたか?他の構文(いいえ別のコマンドでファイルを作成してからchmod)を使用しますか?


両方の環境(LinuxとOS X)で同じバージョンを使用してくださいinstall

$ install --version
install (GNU coreutils) 8.23

ベストアンサー1

OpenBSDシステムにBSDをインストールすると、次のコードがあります(src/usr.bin/xinstall/xinstall.c)。

if (!S_ISREG(to_sb.st_mode))
    errc(1, EFTYPE, "%s", to_name);

エラーが発生します。

install: /dev/fd/4: Inappropriate file type or format

/dev/df/4これが普通のファイルではないことがわかったとき。 (別途早期点検があります/dev/null。)

とても簡単です。

GNUにはinstall次のコード(src/install.cin coreutils)があります:

  /* Allow installing from non-regular files like /dev/null.
     Charles Karney reported that some Sun version of install allows that
     and that sendmail's installation process relies on the behavior.
     However, since !x->recursive, the call to "copy" will fail if FROM
     is a directory.  */

  return copy (from, to, false, x, &copy_into_self, NULL);

エラーを発生させるコードは次のものから来ますsrc/copy.c

  source_desc = open (src_name,
                      (O_RDONLY | O_BINARY
                       | (x->dereference == DEREF_NEVER ? O_NOFOLLOW : 0)));

(数行省略)

  if (fstat (source_desc, &src_open_sb) != 0)
    {
      error (0, errno, _("cannot fstat %s"), quoteaf (src_name));
      return_val = false;
      goto close_src_desc;
    }

  /* Compare the source dev/ino from the open file to the incoming,
     saved ones obtained via a previous call to stat.  */
  if (! SAME_INODE (*src_sb, src_open_sb))
    {
      error (0, 0,
             _("skipping file %s, as it was replaced while being copied"),
             quoteaf (src_name));

copy_reg()通常のファイルがコピーされる場所です。SAME_INODE2つの構造のinodeが異なるため、このマクロはfalseと評価されます。上記のように、ソースファイル名と新しく開かれた記述子を呼び出すか、呼び出しから呼び出します。stat*src_sbsrc_open_sb*src_sbstat()lstat()src_open_sbfstat()

新しいファイルディスクリプタを開いて、そのアイノードをシェルによって提供されたファイルディスクリプタのアノードと比較することが失敗する理由を理解することができますが/dev/fd/4(私の場合)、残念ながらこれを明確な言葉で表現することはできません。

おすすめ記事