새 릴리스 버전으로 업그레이드 한 후 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
실패 하는 상황을 볼 수 있습니다 .
한 가지 해결 방법은 username2
group의 멤버 를 만드는 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