bash : / dev / stderr : 권한이 거부되었습니다 denied 이전 버전의

새 릴리스 버전으로 업그레이드 한 후 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



답변

나는 이것이 전적으로 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다른 계정으로 이동하거나 비슷한 작업을 수행 할 때만 나타납니다 . 단순히 계정에 로그인하면 권한이 올바른 것입니다.


답변

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

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


답변

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

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

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


답변

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

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

echo test > /dev/stderr

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

echo test 1>&2


답변