~ / .zshrc에서 기능을 sudo 할 때“명령을 찾을 수 없습니다”


10

내 기능이 있습니다 ~/.zshrc:

findPort() {
    lsof -t -i :$1
}

일반적인 호출은 findPort 3306입니다.

높은 권한으로 실행하고 싶습니다. 그러나 "명령을 찾을 수 없습니다"라는 메시지가 나타납니다.

  git 🍔 sudo findPort 3306
sudo: findPort: command not found

이유는 루트 사용자가 비 대화식 쉘로 실행하거나 (.zshrc를 참조하지 않음) 다른 것을 참조하기 때문.zshrc 입니다.

에 관한 비슷한 질문을 보았지만 alias사용자 정의 함수에 관한 질문은 없습니다. 이 문제에 대한 답은 다음 alias에 별칭을 추가하는 것입니다 ~/.zshrc.

alias sudo='nocorrect sudo '

또는 아마도 :

alias sudo='sudo '

이 두 가지 솔루션을 모두 시도했지만 문제가 계속 발생합니다 (예 : 셸을 다시 시작했습니다).

또한 sudo chsh루트 쉘이 아래에서 실행되도록 실행 을 시도했습니다 zsh. 이러한 솔루션 중 어느 것도 "명령을 찾을 수 없음"문제를 제거하지 못합니다.

sudo에서 사용자 정의 함수를 실행하는 방법이 있습니까?


참조 : unix.stackexchange.com/questions/181414/...을 (zsh을 자체 트릭이 있기 때문에 신고하지 않음)
muru을

답변:


13

sudo하지 쉘을 통해 직접 명령을 실행하고 그 명령을 실행 쉘을 실행하더라도, 그것은 당신의 읽는 하나의 새로운 쉘 호출, 그리고 않을 것이다 ~/.zshrc(이 대화 형 쉘을 시작하더라도, 그것은 아마 읽을 것 root'들 변수를 재설정하지 않도록 ~/.zshrc구성하지 않는 한 사용자가 sudo아닙니다 $HOME).

여기, sudo새로운 zsh쉘 을 시작 하라고 말하고, 그 기능을 실행하기 전에 zsh읽어 보라고 지시 ~/.zshrc해야합니다.

sudo zsh -c '. $0; "$@"' ~/.zshrc findPort 3306

또는:

sudo zsh -c '. $0; findPort 3306' ~/.zshrc

또는 현재 zsh 함수를 다음에 zsh의해 호출 된 새로운 기능과 공유하십시오 sudo.

sudo zsh -c "$(functions); findPort 3306"

당신은 얻을 수 있지만 너무 오래 인수 목록을 당신이 (완료 시스템을 사용하는 경우 등) 정의 함수의 많은 경우 오류가 발생했습니다. 따라서 findPort함수 (및 함수가있는 경우 다른 모든 함수) 로 제한 할 수 있습니다 .

sudo zsh -c "$(functions findPort); findPort 3306"

당신은 또한 할 수 있습니다 :

sudo zsh -c "(){$functions[findPort]} 3306"

3306 인수를 전달 findPort하는 익명 함수 에 함수 코드를 포함합니다 . 또는:

sudo zsh -c "$functions[findPort]" findPort 3306

(에 전달 인라인 스크립트 -c 함수 본문).

다음과 같은 도우미 기능을 사용할 수 있습니다.

zsudo() sudo zsh -c "$functions[$1]" "$@"

사용하지 마세요:

sdo () {sudo zsh -c "() {$ functions [$ 1]} $ {@ : 2}"}

의 논쟁 sdo은 다른 수준의 쉘 파싱을 겪을 것이다. 비교:

$ e() echo "$@"
$ sdo e 'tname;uname'
tname
Linux
$ zsudo e 'tname;uname'
tname;uname

타이핑만큼 짧은 솔루션이 필요합니다 sudo. 익명의 기능 솔루션 을 적용 할 수있었습니다 . 다음 기능을 my에 추가했습니다. ~/.zshrc기능 은 높은 권한으로 다른 기능 을 실행 하는 기능 입니다.sdo() { sudo zsh -c "(){$functions[$1]} ${@:2}" }
Birchlabs

1
@Birchlabs, 편집 참조
Stéphane Chazelas

감사; 제안한 최신 바로 가기를 사용하도록 답변을 업데이트했습니다.
Birchlabs

sudo를 통해 실행 된 스크립트에 함수 정의를 추가하는 것이 현명합니다. 그러나 해당 기능이 다른 기능 (자동로드 여부)을 사용하는 경우 충분히 똑똑하지 않습니다.
Damien Flament

3

매우 간단한 해결책은 sudo -smacOS 번들 버전의 zsh (5.2)에서 작동하는 것처럼 보이는을 사용하여 대화식 쉘을 호출하는 것 입니다. 이것은 내 기능을 제공합니다.~/.zshrc .

sudo 맨 페이지에서이 동작을 실제로 암시하지는 않습니다.

-s, --shell
SHELL 환경 변수에 의해 지정된 쉘 (설정된 경우) 또는 호출하는 사용자의 암호 데이터베이스 항목에 의해 지정된 쉘을 실행하십시오. 명령이 지정되면 쉘의 -c 옵션을 통해 실행되도록 쉘로 전달됩니다. 명령을 지정하지 않으면 대화식 쉘이 실행됩니다.

유스 케이스가 무엇인지 잘 모르겠지만 대화 형 솔루션을 찾고 있다고 생각합니다.


이것은 실제로 작동합니다. 비록 내가 생각했던 워크 플로우는 아니지만. 내 욕망은 평소 사용자로 프롬프트에 남아 있고, 내 사용자 정의 함수를 높이는 것입니다 myFunc입력하여, sudo myFunc- 나는 상승하는 것과 같은 방식으로 어떤 과정 (등을 sudo rm -rf .). 이 솔루션은 나의 모든 신속한 기능과 미래의 모든 기능을 향상시킬뿐만 아니라 미래의 모든 기능을 위해 사용자를 변경합니다.
Birchlabs

sudo -s명령은 쉘의 다른 인스턴스를 수퍼 유저로 시작합니다. 해당 명령을 대화식으로 실행하면 새 셸이 대화식이됩니다. 그러나 명령 sudo -s findPort 3306findPort 3306수퍼 유저로서 쉘에서 명령 을 실행 한 다음 해당 명령의 상태 코드로 종료합니다.
Damien Flament

2

재사용 가능한 속기 를 만들 수있었습니다 Stéphane Chazelas의 답변에 설명 된 솔루션 중 하나에 대한 . [편집 : Stéphane은 내가 제안한 원래 바로 가기를 반복했습니다. 여기에 설명 된 코드는 그의 최신 버전입니다.]

이것을 당신의 것으로 ~/.zshrc :

sdo() sudo zsh -c "$functions[$1]" "$@"

이제 사용할 수 있습니다 sdo "sudo 사용자 정의 함수 전용"으로 .

sdo작동 하는지 확인하려면 : 사용자 이름을 인쇄하는 사용자 정의 함수에서 시도해 볼 수 있습니다.

 birch@server ~/ 🍔 test() whoami

 birch@server ~/ 🍔 test
birch

 birch@server ~/ 🍔 sdo test
root

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