7

I would like to use install command in order to create a new executable file with pre-populated content (e.g. with single pwd command in it).

So I've extended this example which creates a new empty executable file:

install -b -m 755 /dev/null newfile

into this one:

install -m755 <(echo pwd) newfile

or:

echo pwd | install -m755 /dev/stdin newfile

Where I expect to create a new newfile executable file to be created with content pwd inside.

It works on Linux, however on OS X it fails with the following error:

  • BSD install (/usr/bin/install)

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

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

    install: skipping file /dev/fd/63, as it was replaced while being copied

Why this doesn't work on Unix, but it works on Linux? I'm missing anything? Is there any way to bypass the above warning by using different syntax (without creating a file in separate commands and using chmod after that)?


On both environments (Linux & OS X) I've the same version of install:

$ install --version
install (GNU coreutils) 8.23
kenorb
  • 20,988
  • 1
    I just tried the syntax install -m755 <(echo pwd) newfile on a centOS 7 machine, and it worked correctly. using the syntax install -m755 <(echo pwd)> newfile produced the error you are receiving though. I realize this doesn't implicitly help you, but it does show that your premise is sound at least. It should be working – Gravy Oct 13 '15 at 03:36
  • May be better to ask on http://codegolf.stackexchange.com/ . – Mark Plotnick Oct 13 '15 at 08:36
  • @MarkPlotnick At golf they don't like shell challenges. I've simplified question, as Gravy hint helped me to point, that it actually suppose to work, but it isn't as expected. So it actually isn't challenge, but a specific command syntax question. – kenorb Oct 13 '15 at 08:44
  • OK, I see the edited question no longer has puzzle-like constraints. – Mark Plotnick Oct 13 '15 at 09:49
  • 2
    If you use zsh, you may try the =(cmd) syntax instead of <(cmd). From the man: "If =(...) is used instead of <(...), then the file passed as an argument will be the name of a temporary file containing the output of the list process. This may be used instead of the < form for a program that expects to lseek (see lseek(2)) on the input file." Otherwise mkfifo is your best bet. – Michaël Nov 17 '15 at 16:09
  • @kenorb I don't know what version of OS X you're using, but certainly on mine (10.11.3, El Capitan), install is part of the BSD suite, not GNU. Unless you're using homebrew to install custom versions of cmds, anything you use will be the BSD version and therefore differ in functionality from those of GNU Linux. – toxefa Mar 09 '16 at 20:35
  • @py4on You're correct. I've different error with BSD install. I've updated with clarification. – kenorb Mar 09 '16 at 20:40
  • 1
    @kenorb I'm don't know if you've come across this in you're own research into the problem, but your error message seems to have been widespread amongst Cygwin users, most often using cp. This is just one example: http://permalink.gmane.org/gmane.os.cygwin/129935 – toxefa Mar 09 '16 at 20:48
  • 1
    @py4on I've found by accident when experimenting with creation of executable file with content which I wanted to achieve in one go. So it was working on Linux VM, but when tested locally on OS X, to my surprise it failed. – kenorb Mar 09 '16 at 20:52
  • 1
    @kenorb Ok, looks like this is considered a kernel bug (reported on RedHat https://goo.gl/Bc2xx2 and Samba https://goo.gl/tf4IdG bugzillas) which was patched in kernel 2.6.36. – toxefa Mar 09 '16 at 21:19
  • 2
    @py4on How this is related to OS X kernel? This happens on Mac for both install versions. – kenorb Mar 09 '16 at 21:23
  • 2
    Unless they share the same bug with some similar code. – kenorb Mar 09 '16 at 21:34
  • It's impossible to have same versions! OS X is using BSD version of Install, while Linux Distros are using GNU coreutils! The only thing is common, is the name of it, even options provide slight different jobs! –  Jul 23 '16 at 11:54

1 Answers1

1

The BSD install found on OpenBSD systems has this piece of code in it (from src/usr.bin/xinstall/xinstall.c):

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

This emits the error

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

when it's discovered that /dev/df/4 is not a regular file. (There's a separate earlier check for /dev/null)

That was fairly straight forward.

GNU install has this code (src/install.c in 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);

The code emitting the error comes from src/copy.c:

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

(a few lines omitted)

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

This is in copy_reg() which copies a regular file. The SAME_INODE macro evaluates to false because the inodes differ in the two stat structs *src_sb and src_open_sb. The *src_sb comes from a stat() or lstat() call on the source file name and src_open_sb from fstat() as seen above, on a newly open descriptor.

I can kinda see why opening a new file descriptor and comparing its inode to that of the file descriptor given by the shell (/dev/fd/4 in my case) will fail, but I can't put it into definite words unfortunately.

Kusalananda
  • 333,661