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_INODE두 구조의 inode가 다르기 때문에 이 매크로는 false로 평가됩니다 . 위에 표시된 대로 소스 파일 이름과 새로 열린 설명자를 또는 호출에서 호출합니다.stat*src_sbsrc_open_sb*src_sbstat()lstat()src_open_sbfstat()

새 파일 설명자를 열고 그 아이노드를 셸에서 제공한 파일 설명자의 아이노드와 비교하는 것이 실패하는 이유를 이해할 수 있지만 /dev/fd/4(내 경우에는) 안타깝게도 이를 명확한 단어로 표현할 수 없습니다.

관련 정보