我想使用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
答案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
)
这相当简单。
GNUinstall
有以下代码(src/install.c
在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, ©_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 给出的文件描述符的 inode 进行比较(/dev/fd/4
在我的例子中)会失败,但不幸的是我无法用明确的词来表达。