bash : / dev / stderr : 권한이 거부되었습니다


19

새 릴리스 버전으로 업그레이드 한 후 bash스크립트에서 오류가 발생하기 시작합니다.

bash: /dev/stderr: Permission denied

이전 버전의 배쉬는 것 내부적으로 인식 (이 질문의 중복되지 않는 이유 인 그 파일 이름 이 하나 )과 정당한 일 (TM)을 할 , 그러나, 이것은 지금 작동이 중지되었습니다. 스크립트를 다시 성공적으로 실행하려면 어떻게해야합니까?

스크립트를 실행하는 사용자를 그룹에 추가하려고 시도했지만 tty로그 아웃했다가 다시 로그인해도 차이가 없습니다.

문제없이 명령 줄에서 이것을 재현 할 수 있습니다.

$ echo test > /dev/stdout
bash: /dev/stdout: Permission denied
$ echo test > /dev/stderr
bash: /dev/stderr: Permission denied
$ ls -l /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stdout -> /proc/self/fd/1
$ ls -lL /dev/stdout /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stdout
$ echo $BASH_VERSION
4.2.24(1)-release

구형 시스템 (Ubuntu 10.04) :

$ echo $BASH_VERSION
4.1.5(1)-release

1
ls -l /dev/stdout /dev/stderr과 의 출력은 무엇입니까 ls -lL /dev/stdout /dev/stderr?
키이스 톰슨

@ Keith : 편집 된 질문을 참조하십시오. 이것은 Bash가 이것의 내부 처리를 완전히 포기했음을 의미합니까? 구형 시스템에서는 이러한 심볼릭 링크가 존재하지 않았지만 코드는 문제없이 작동했습니다. 참고이를 통해 가장 한 실행 sudo su username2 -...
0xC0000022L

어떤 bash 버전을 사용하고 있습니까? echo $BASH_VERSION
jippie

1
이전 버전과 새로운 버전 (OS 및 bash 전후)
Keith Thompson

답변:


41

나는 이것이 전적으로 bash 문제 라고 생각하지 않습니다 .

코멘트에서, 당신은 당신이 한 후에이 오류를 보았다고 말했다

sudo su username2

로 로그인 할 때 username. 그것이 su문제를 일으키는 것입니다.

/dev/stdout심볼릭 링크이다 /proc/self/fd/1예 심볼릭 링크이다, /dev/pts/1. /dev/pts/1의사 터미널 인,는 소유하고 쓰기 가능합니다 username. username로그인 하면 소유권이 부여됩니다 .의 sudo su username2경우 소유권이 /dev/pts/1변경 username2되지 않으며 쓰기 권한이 없습니다.

나는 이것이 버그라고 주장한다. 사실상 표준 출력 스트림의 별칭 /dev/stdout 이어야 하지만 여기서는 echo hello작동하지만 echo hello > /dev/stdout실패 하는 상황을 볼 수 있습니다 .

한 가지 해결 방법은 username2group의 멤버 를 만드는 tty것이지만 tty username2에 쓸 수 있는 권한을 부여하므로 바람직하지 않습니다.

다른 해결 방법은을 username2사용하지 않고 계정 에 로그인 하여을 소유 한 새로 할당 된 유사 터미널 su/dev/stdout가리 킵니다 username2. 실용적이지 않을 수 있습니다.

또 다른 해결 방법은 스크립트가 /dev/stdout및을 참조하지 않도록 수정하는 것입니다 /dev/stderr. 예를 들어 다음을 바꾸십시오.

echo OUT > /dev/stdout
echo ERR > /dev/stderr

이로 인해:

echo OUT
echo ERR 1>&2

나는 bash는 4.2.24로, 내 자신의 시스템, 우분투 12.04에서이 참조 - bash는 문서 (비록 info bash내 시스템)를 말한다 /dev/stdout/dev/stderr리디렉션에 사용할 때 특별히 처리됩니다. 그러나 bash가 해당 이름을 특수하게 처리하지 않더라도 표준 I / O 스트림과 동등한 역할을 수행해야합니다. (POSIX는 언급하지 않으므로 /dev/std{in,out,err}이것이 버그라고 주장하기 어려울 수 있습니다.)

이전 버전의 bash를 살펴보면 문서 /dev/stdout는 파일의 존재 여부에 상관없이 특별히 처리 된다는 것을 암시합니다 . 이 기능은 bash 2.04에서 도입되었으며 NEWS해당 버전 의 파일은 다음과 같습니다.

리디렉션 코드는 이제 파일 시스템에 있는지 여부에 관계없이 / dev / fd / N, / dev / stdin, / dev / stdout 및 / dev / stderr과 같은 여러 파일 이름을 처리합니다.

그러나 소스 코드 ( redir.c) 를 살펴보면 심볼 이 정의 된 경우 에만 특수 처리가 가능하다는 것을 알 수 있습니다 HAVE_DEV_STDIN(이것은 소스에서 bash가 빌드 될 때 결정됨).

내가 알 수있는 한, bash의 릴리스 버전은 일부 배포판이 패치하지 않은 한 기타 조건을 특수하게 처리 하지 않았습니다/dev/stdout .

따라서 시도하지 않은 또 다른 해결 방법은 bash 소스 를 가져 와서 redir.c특수 /dev/*처리를 무조건으로 수정 하고 시스템과 함께 제공된 버전이 아닌 재구성 된 버전을 사용하는 것입니다. 그러나 이것은 아마도 과잉 일 것입니다.

요약 :

당신의 OS는 광산처럼, 소유권 및 권한 처리되지 /dev/stdout/dev/stderr제대로을. bash는 가정으로 재 지정에 특별히 이러한 이름을 취급하지만, 사실 그것은 파일이 존재하지 않는 경우에만 수정한다. 경우에 그것은 문제가되지 것 /dev/stdout하고는 /dev/stderr제대로 작동했다. 이 문제는 su다른 계정으로 이동하거나 비슷한 작업을 수행 할 때만 나타납니다 . 단순히 계정에 로그인하면 권한이 올바른 것입니다.


TTY의 소유권이 변경되어야합니다. 이것이 바로 ConsoleKit (일명 pam_ck_connector.so)입니다.
Mikel

사실, 나는 틀릴 수 있습니다. 더 파야 할 것입니다.
Mikel

내 시스템에서 /proc/self/fd/1사용 권한이 업데이트되었지만 심볼릭 링크이므로 의미가 없습니다. Fedora에서도 발생합니다. ConsoleKit을 배제한 것으로 보입니다.
Mikel

1

실제로 이것은 udev가 tty 장치에서 권한을 0620으로 설정하고 su가 소유권이나 권한을 변경하거나 변경하지 않기 때문입니다. 제 생각에 이것은 / dev / std *를 이식 할 수없는 상황으로 만듭니다.

간단한 해결책은 tty 장치의 권한을 0622로 변경하기 때문에 "mesg y"를 / etc / profile (또는 사용하려는 최상위 프로파일)에 넣는 것입니다. udev 규칙을 변경하는 것보다.


"msg y"가 작동하지 않음
Luciano

아마도 ... Bash를 검색하면 Bash 맨 페이지의 리디렉션사용될 때 특히 여러 파일 이름을 처리합니다 .
0xC0000022L

0

오랫동안 Linux 사용자로서 나는 최근에 새로운 Ubuntu 64 비트 12.04 LTS 시스템을 설치했으며 왜 내 bash 스크립트가 작동하지 않는지 (허가 거부)이 스레드를 찾았습니다. 새로운 OS에 문제가 있다고 생각했습니다.

결국 나는 UI 도구를 바보로 사용하여 /home디렉토리 에 대한 권한을 설정 했으며 문제는 드라이브와 관련 이 있음이 밝혀졌습니다 . 확실히하기 위해 temp디렉토리를 만들었고 /opt스크립트가 제대로 실행되는 것을 알았습니다. /home드라이브 권한을 수정하면 모든 것이 정상으로 돌아 왔습니다.

작은 미스터리가 풀렸다. 한숨


2
다른 오류 였을 것입니다. / home에서 무언가를 수정해도 / dev에는 영향을 미치지 않습니다.
ott--

-1

이것은 오래된 질문이지만 여전히 매우 관련이 있다고 생각하므로 여기에 언급되지 않은 해결책이 있습니다.

bash에서 다음과 같은 명령을 실행하는 'su'전환 계정에서 문제를 보았 으므로이 질문을 보았습니다.

echo test > /dev/stderr

내가하려고하는 것은 stdout을 stderr로 리디렉션하는 것이므로 다음과 같은 결과가 나오며 'su'교환 계정에서도 작동합니다.

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