출력을 리디렉션 할 때 특정 파일 권한을 설정하는 방법은 무엇입니까?


12

이것은 중복 일 수 있지만 모든 검색에서 권한 거부 오류에 대한 질문이 표시됩니다.

bash 쉘에서 명령을 실행 중입니다. 첫 번째 실행에 존재하지 않는 파일에 추가하기 위해 출력을 리디렉션하고 싶습니다. 출력 리디렉션이이 파일을 만들어야하는 경우 특정 파일 권한 모드를 설정하고 싶습니다. 하나의 명령으로 이것을 수행하는 방법이 있습니까?

예를 들어, 시도해 볼 수 있습니다

foo >> /tmp/foo.log 0644

0644내가 foo.log끝내려 는 권한은 어디에 있습니까 ? bash에서 실험 한 대부분의 명령 0644은에 대한 추가 인수로 해석 됩니다 foo.

나는 이것이 chmod쓰기 전후에 권한에 대한 두 번째 명령을 내릴 것이라고 생각 합니다.

GNU bash 4.2.25와 Ubuntu 12.04를 사용하고 있습니다. 차이가 있다면 일반적인 대답이 선호됩니다.

답변:


5

내가 아는 한 배관하는 동안 할 수있는 방법이 없습니다. 간단한 스크립트가 가장 좋은 해결책 일 수 있습니다.

if [ -e /tmp/foo.log ]; then
    foo >> /tmp/foo.log
else
    foo >> /tmp/foo.log
    chmod 0644 /tmp/foo.log
fi

고마워 Slowki, 그것은 또한 나의 직감이었다. 나는 우리를 계몽시키기 위해 전문가를 유치하기 위해 며칠 동안 열어 두겠습니다.
Patrick M

3
이 방법의 문제점은 파일에 대한 권한이 잘못되었을 때 짧은 시간 창을 생성한다는 것입니다. 중요한 데이터를 보호하는 것이 목표라면 사용하지 않을 것입니다.
proski

1
이 답변은 가능한 한 효과가 있지만 @proski는 옳습니다. umask답변이 더 좋으며 그중 하나를 수락해야합니다.
Scott

15

나는 그것이 오래된 질문이라는 것을 알고 있지만 2 센트를 더하고 싶었습니다.

나는 같은 생각을 가지고 BowlesCR 과 비슷한 솔루션을 생각해 냈습니다 . 그의 솔루션의 문제는 foo실행하기 전에 umask를 변경하면 내 명령 ( )이 작동하지 않는다는 것입니다.

foo | ( umask 0033; cat >> /tmp/foo.log; )

여기서는 서브 쉘에서의 umask리디렉션에만 영향을줍니다 foo.log. 다른 모든 것은 영향을받지 않습니다.

약간 복잡하지만 작동합니다.


매우 훌륭하고 효과적입니다 :) stdout redir 상단의 stderr 리디렉션과 함께 사용할 수 없습니다.
Orsiris de Jong

5

진정한 스크립팅을 사용하지 않으면 약간 연결할 수 있습니다.

touch /tmp/foo.log; chmod 0644 /tmp/foo.log; foo >> /tmp/foo.log

Slowki의 답변 과 효과적으로 유사 하지만 하나의 라이너로 압축되었습니다.

내가 생각할 수있는 유일한 다른 것은 umask로 땜질하는 것입니다. 현재 환경을 오염시키지 않도록 서브 쉘에서이를 수행하는 것이 가장 좋습니다.

(umask 0033 && foo >> /tmp/foo.log)

그러나 두 가지 문제가 있습니다.

  1. Umask는 creat()syscall에 지정된 수준 이상으로 권한을 올릴 수 없습니다 (0666은 Bash가 사용하는 것으로 보입니다).
  2. 기존 파일에 대한 권한은 변경되지 않습니다 ( umask파일 생성 에만 적용 되기 때문 ).

나는 umask가 여전히 나에게 약간의 마술이라는 것을 * nix에 충분히 익숙합니다. 팁 주셔서 감사합니다, 나는 그것에 대해 읽어 드리겠습니다.
Patrick M

흠 ... 여전히 권한이없는 프로세스가 파일을 열고 나중에 내용을 읽을 수 없습니다.
Feuermurmel

(1)의 유용 하고 유용한 사용법 을 찾은 것을 축하합니다 cat. (이것은 쓸모없는 사용의 표준 패턴을 따르지 않지만  cat) (2) 파일을 만들 때 bash가 기본 모드 0666 으로 설정  되어 있다고 대답했다고 가정합니다. (참조 ,    ) ... (계속을
스콧

(계속)… and  this .)이 질문에는 모드 0644가 구체적으로 언급되어 있습니다. 따라서 umask22, 23 또는 32 의 값도 이와 관련하여 작동합니다 (앞의 0을 사용할 필요가 없습니다. 모드와  umask값은 숫자로 지정되며 항상 8 진수로 해석됩니다.  22 더 일반적으로 사용됩니다.
Scott

@Feuermurmel : 그래서 무엇? 이 질문은 명백하게 모드 644를 요구한다. 우리는 OP 644가 세계가 읽을 수 있고 자신의 정보를 공개 할 것을 의미한다는 것을 알고 있다고 가정해야한다 .
Scott

1

리디렉션이 잘못된 권한을 설정 한 경우

$ rm capture.*
$ perl -e 'print STDERR "$$ STDERR\n"; print STDOUT "$$ STDOUT\n"' \
                            >> capture.STDOUT 2>> capture.STDERR
$ perl -e 'print STDERR "$$ STDERR\n"; print STDOUT "$$ STDOUT\n"' \
                            >> capture.STDOUT 2>> capture.STDERR
$ ls -l capture.*
-rw-rw-rw- 1 jcookinf jcookinf 22 Jun 12 10:38 capture.STDERR
-rw-rw-rw- 1 jcookinf jcookinf 22 Jun 12 10:38 capture.STDOUT
$ cat capture.*
215 STDERR
216 STDERR
215 STDOUT
216 STDOUT

xynomorf와 같은 것을 사용하고 bash 프로세스 대체 를 사용하도록 약간 수정하여 Orsiris de Jong의 stderr 우려를 해결할 수 있다고 생각합니다 .

$ rm capture.*
$ perl -e 'print STDERR "$$ STDERR text\n"; print STDOUT "$$ STDOUT text\n"' \
            > >(umask 0033; cat >> capture.STDOUT) 2> >(umask 0033; cat >> capture.STDERR)
$ perl -e 'print STDERR "$$ STDERR text\n"; print STDOUT "$$ STDOUT text\n"' \
            > >(umask 0033; cat >> capture.STDOUT) 2> >(umask 0033; cat >> capture.STDERR)
$ ls -l capture.*
-rw-r--r-- 1 jcookinf jcookinf 32 Jun 12 10:43 capture.STDERR
-rw-r--r-- 1 jcookinf jcookinf 32 Jun 12 10:43 capture.STDOUT
$ cat capture.*
233 STDERR text
238 STDERR text
233 STDOUT text
238 STDOUT text

당연히 umask 0077모드를 사용 하고 600 다른 사용자가 내용을 보지 못하도록하는 데 사용하십시오.


0

umask프로세스 대체를 사용 하여과 달리 스크립트로 리디렉션 install하고 실행 비트를 설정할 수도 있습니다.

install -m 755 <(echo commands go here) newscript

<()출력을 임시 파일에 배치합니다 ( 프로세스 대체 참조).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.