Shell

當 Linux 上相同版本的“安裝”工作正常時,為什麼 OS X 在重定向輸入上會出現“安裝”錯誤?

  • July 23, 2016

我想使用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)

install: /dev/fd/63: 不適當的文件類型或格式

  • GNU 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

在 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

那是相當直截了當的。

GNUinstall有這個程式碼(src/install.ccoreutils):

 /* 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()其中複製正常文件。該宏的計算結果為 false,因為兩個結構SAME_INODE中的 inode和. 來自源文件名的 or 呼叫,如上所示,來自新打開的描述符。stat``*src_sb``src_open_sb``*src_sb``stat()``lstat()``src_open_sb``fstat()

我有點明白為什麼打開一個新的文件描述符並將其 inode 與 shell(/dev/fd/4在我的情況下)給出的文件描述符的 inode 進行比較會失敗,但不幸的是我無法用明確的語言表達。

引用自:https://unix.stackexchange.com/questions/235687