Bash에서 리디렉션과 함께 sudo를 사용할 때 "권한 거부"를 해결하는 방법은 무엇입니까?


137

sudo를 사용하여 파일을 편집 할 때 정기적으로 'permission denied'가 표시됩니다.

예를 들어, 마우스가 불안하고 느리기 때문에 폴링을 비활성화하고 싶습니다.

sudo echo "options drm_kms_helper poll=N">/etc/modprobe.d/local.conf

암호를 묻는 메시지가 나타나면 다음을 얻습니다.

bash: /etc/modprobe.d/local.conf: Permission denied

그래서 다음을 사용하여 폴링을 비활성화하기 위해 임시 변경을 시도했습니다.

sudo echo N> /sys/module/drm_kms_helper/parameters/poll

그러나 다시 시스템은 다음과 같이 응답했습니다.

bash: /sys/module/drm_kms_helper/parameters/poll: Permission denied

어떤 아이디어?

답변:


156

>연산자 를 통한 출력 리디렉션 은 echo가 아니라 셸에 의해 수행됩니다 . 루트로 로그인해야합니다

sudo -i

그런 다음 리디렉션을 사용할 수 있습니다

echo N> /sys/module/drm_kms_helper/parameters/poll

그렇지 않으면 sudo로 bash 문자열을 실행할 수 있습니다

sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"

1
sudo로 echo를 실행할 수 없습니까? 뭐라고 내가 가진 결과에 대한 :saji@laptop:~$ sudo echo "Hi" [sudo] password for saji: Hi
saji89

파일에 쓰거나 "뭔가"를 반향시킬 수 있습니다. 파이프를 사용하고 있습니다. 문제입니다.
shantanu

4
그렇다면, 그렇다면 에코 실행이 문제라는 것을 반영하여 답변을 업데이트하십시오.
saji89

echo같은 것을하지 않으면 쉘 내장 sudo를 단순히 실행할 수 없다 sudo bash -c 'echo …'. 그러나 POSIX 시스템은 일반적 으로 OS X echo와 같은 외부 명령을 제공하며 /bin/echosudo는 rigamarole없이 실행할 수 있습니다. 따라서 echo일반적으로 실행하는 echo명령과 sudo로 실행 하는 명령은 서로 다르지만 유사한 명령 일 수 있습니다.
kojiro

그렇다면 왜이 질문에 대한 답이 에코를 제안 했습니까? askubuntu.com/questions/840431/…
하르샤

75

출력 재 지정은 명령이 호출 된 쉘에 의해 수행 됩니다 . 따라서 모든 것을 비트로 나누면 여기에서 무슨 일이 일어나는지 * :

  • shell은 명령 행 으로 명령 sudo echo "options drm_kms_helper poll=N"을 실행하는을 호출합니다 .sudoecho "options drm_kms_helper poll=N"

  • sudo는 암호를 요청하고 수퍼 유저 쉘을 열고 명령 echo "options drm_kms_helper poll=N"을 실행 하여 암호를 echo전달합니다."options drm_kms_helper poll=N"

  • root권한으로 실행되는 echo 는 문자열을 표준 출력으로 인쇄합니다.

  • echo명령 종료, 수퍼 유저 셸 종료, sudo종료

  • 명령이 호출 된 쉘은 출력을 수집하고이를 /etc/modprobe.d/local.conf루트로만 재 지정할 수있는로 경로 재 지정하려고 시도 합니다. "권한 거부"오류가 발생합니다.

이 문제를 해결하는 방법은 @shantanu answer를 참조하십시오.


(*)-위의 순서는 명령이 실패한 이유를 이해하는 데 도움이되지만 실제로는 순서가 잘못되었습니다. 원래 쉘은 경로 재 지정을 확인하고 sudo ...명령을 호출하기 전에 파일을 열어 쓰기 위해 시도합니다 . 파일을 열지 못하면 셸은 파일에 쓰려고했던 명령조차 호출하지 않습니다 (이를 지적한 @PanosRontogiannis 덕분입니다).

다음은 간단한 테스트입니다.

$ touch ./onlyroot.txt
$ sudo chown root:root ./onlyroot.txt
$ sudo bash -c "whoami | tee who.txt" > onlyroot.txt
bash: onlyroot.txt: Permission denied

위의 테스트에서 "root"라는 단어가 포함 whoami | tee who.txt된 파일을 작성하려고했습니다 who.txt. 그러나 호출 쉘에서 출력 경로 재 지정이 실패하면 명령이 호출되지 않아서 "who.txt"파일도 누락됩니다.


쉘을 '포크'하고 sudo를 'exec'하기 전에 /etc/modprobe.d/local.conf를 열려고 시도했을 가능성이 높습니다. 이는 파일을 열 수 없기 때문에 설명하는 첫 4 단계가 실제로 발생하지 않음을 의미합니다.
Panos Rontogiannis 2016 년

1
@PanosRontogiannis : 감사합니다. 정답을 업데이트했습니다
Sergey

60

Shantanu의 답변에 추가 :

... 또는 다음 tee과 같은 명령을 사용할 수 있습니다 .

sudo tee /sys/module/drm_kms_helper/parameters/poll <<<10

또는 명령의 출력 인 경우 :

echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll

3
루트 수동 작업에 대한 나쁜 생각하고 있습니다로 한 로깅 정말 대본 작업에 대한 나쁜 생각.
l0b0

2
또한 sudo tee /sys/module/drm_kms_helper/parameters/poll > /dev/null인쇄하고 싶지 않은 경우 stdout.
Fabian Tamp

16

여기서 언급하지 않은 방법은 전체 명령 줄을 자체 쉘에서 간단히 실행하는 것입니다. sudo맨 페이지 자체가이 방법의 예를 제공합니다 :

/ home 파티션에있는 디렉토리의 사용법 목록을 작성합니다. 이 명령은 CD 및 파일 리디렉션이 작동하도록 하위 셸에서 명령을 실행합니다.

$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"

와우 감사합니다. 간단한 솔루션
복원력

4

다른 옵션은 임시 파일을 사용하는 것입니다. 이것은 bash 스크립트에서 유용합니다.

temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever

3

sudo dd of=

원하는대로 추가하려면 :

echo inbytes | sudo dd of=outfile oflag=append conv=notrunc

또는 처음부터 파일을 다시 작성하려면 다음을 수행하십시오.

echo inbytes | sudo dd of=outfile

장점 :

  • 리디렉션 이 tee없기 때문에/dev/null
  • sh명시 적 서브 쉘 이 없기 때문에 (그러나 리디렉션을위한 암시 적 서브 쉘)
  • ddstatus=progress전송 진행 상황을 볼 수있는 많은 강력한 옵션이 있습니다.

sudo가 stdin을 명령으로 전달하기 때문에 작동합니다.


1
이거 좋다 우리는 dd우리가 한때 위대한 파일 시스템을 덮어 쓰는 방법으로 생각 하고, 그것이 평범한 작업을위한 것임을 깨닫지 못합니다. 그리고 다른 명령이 루트 인 다른 명령도 잘못된 파일 / 장치에서 사용될 경우 큰 해를 끼칩니다. 마찬가지로sudo tee , sudo dd물론도 함께 작동합니다 여기에 문자열 , 예를 들어, sudo dd of=outfile <<<'hello world'. [편집 해 주셔서 감사합니다. 와 NB는 sh -c 'cmd', sh정말 의미에서 제외 서브 쉘이 아닌 쉘, 그러나 서브 프로세스입니다 모든 외부 명령 하나로 시작].
엘리야 케이건
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.