Warum werden OS X-Fehler bei umgeleiteten Eingaben "installiert", wenn dieselbe Version von "install" unter Linux einwandfrei funktioniert?

7

Ich möchte den installBefehl verwenden, um eine neue ausführbare Datei mit vorab ausgefülltem Inhalt zu erstellen (z. B. mit einem einzelnen pwdBefehl).

Also habe ich dieses Beispiel erweitert, das eine neue leere ausführbare Datei erstellt:

install -b -m 755 /dev/null newfile

in diesen:

install -m755 <(echo pwd) newfile

oder:

echo pwd | install -m755 /dev/stdin newfile

Wo ich erwarte, eine neue newfileausführbare Datei zu erstellen, die mit Inhalten pwddarin erstellt wird.

Es funktioniert unter Linux, schlägt jedoch unter OS X mit dem folgenden Fehler fehl:

  • BSD install( /usr/bin/install)

    install /dev/fd/63:: Unangemessener Dateityp oder Format

  • GNU install( /usr/local/opt/coreutils/libexec/gnubin/install)

    install: Datei /dev/fd/63wird übersprungen , da sie beim Kopieren ersetzt wurde

Warum funktioniert das nicht unter Unix, aber unter Linux? Ich vermisse etwas? Gibt es eine Möglichkeit, die obige Warnung mit einer anderen Syntax zu umgehen ( ohne eine Datei in separaten Befehlen zu erstellen und chmoddanach zu verwenden)?


In beiden Umgebungen (Linux & OS X) habe ich dieselbe Version von install:

$ install --version
install (GNU coreutils) 8.23
Kenorb
quelle
1
Ich habe gerade die Syntax install -m755 <(echo pwd) newfileauf einer centOS 7Maschine ausprobiert und sie hat korrekt funktioniert. Die Verwendung der Syntax install -m755 <(echo pwd)> newfileführte jedoch zu dem Fehler, den Sie erhalten. Mir ist klar, dass dies Ihnen nicht implizit hilft, aber es zeigt, dass Ihre Prämisse zumindest solide ist. Es sollte funktionieren
Soße
2
Wenn Sie verwenden zsh, können Sie die =(cmd)Syntax anstelle von versuchen <(cmd). Vom Mann: "Wenn =(...)anstelle von verwendet wird <(...), ist die als Argument übergebene Datei der Name einer temporären Datei, die die Ausgabe des Listenprozesses enthält. Dies kann anstelle des <Formulars für ein Programm verwendet werden, das dies erwartet lseek(siehe lseek(2)) in der Eingabedatei. " Ansonsten mkfifoist Ihre beste Wahl.
Michaël
1
@kenorb Ich weiß nicht, ob Sie dies bei Ihrer eigenen Untersuchung des Problems festgestellt haben, aber Ihre Fehlermeldung scheint unter Cygwin-Benutzern weit verbreitet gewesen zu sein und wird am häufigsten verwendet cp. Dies ist nur ein Beispiel: permalink.gmane.org/gmane.os.cygwin/129935
Toxefa
2
@ py4on Wie hängt das mit dem OS X-Kernel zusammen? Dies geschieht auf dem Mac für beide installVersionen.
Kenorb
2
Es sei denn, sie haben denselben Fehler mit einem ähnlichen Code.
Kenorb

Antworten:

1

Die auf OpenBSD-Systemen gefundene BSD-Installation enthält diesen Code (von src/usr.bin/xinstall/xinstall.c):

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

Dies gibt den Fehler aus

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

Wenn festgestellt wird, dass /dev/df/4es sich nicht um eine reguläre Datei handelt. (Es gibt eine separate frühere Prüfung für /dev/null)

Das war ziemlich einfach.

GNU installhat diesen Code ( 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);

Der Code, der den Fehler ausgibt, stammt von src/copy.c:

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

(ein paar Zeilen weggelassen)

  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));

Hier wird copy_reg()eine reguläre Datei kopiert. Das SAME_INODEMakro wird als falsch ausgewertet, da sich die Inodes in den beiden statStrukturen *src_sbund unterscheiden src_open_sb. Das *src_sbkommt von einem stat()oder lstat()Anruf auf dem Quelldateinamen und src_open_sbvon fstat()oben gesehen, auf einen neu geöffneten Descriptor.

Ich kann sehen, warum das Öffnen eines neuen Dateideskriptors und der Vergleich seines Inodes mit dem des von der Shell angegebenen Dateideskriptors ( /dev/fd/4in meinem Fall) fehlschlägt, aber ich kann ihn leider nicht in bestimmte Worte fassen.

Kusalananda
quelle