sudo를 사용하여 일부 명령줄 명령 실행

sudo를 사용하여 일부 명령줄 명령 실행

나는 이것을 실행한다

time sudo nice -n -20 bash myscript.sh

그런 다음 Myscript.sh는 일부 파일을 처리하고 그 결과를 사용하여 파일을 만듭니다.

여기에는 두 가지 문제가 있습니다.

  • 이 스크립트는 루트로 실행됩니다.
  • 생성된 파일은 루트가 소유합니다.

나는 스크립트가 루트 권한으로 실행되는 것을 원하지 않으며(실수하여 중요한 내용을 삭제하기 시작하는 경우 등) 출력은 내 것이 되어야 합니다.

스크립트의 우선순위를 변경하려면 sudo가 필요한데, 일반 사용자로 스크립트를 실행하려면 어떻게 해야 하나요?

답변1

uid와 gid를 다시 전환해야 합니다. zsh할당을 사용하면 $USERNAME사용자가 다른 변경 사항 없이 방금 로그인한 것처럼 모든 uid, euid, gid 등을 해당 사용자의 것으로 변경할 수 있습니다.

sudo nice -n -20 zsh -c 'USERNAME=$SUDO_USER; exec bash ./myscript.sh'

또는:

sudo nice -n -20 su "$LOGNAME" -c 'exec bash ./myscript.sh'

또는:

sudo nice -n -20 sudo -u "$LOGNAME" bash ./myscript.sh

그러나 여기에는 PAM 스택을 다시 확인하고 상태 재설정을 포함하여 환경에 대한 추가 변경(필요할 수도 있고 필요하지 않을 수도 있음)이 포함될 수 있습니다.

그럼에도 불구하고, 이전에 가지고 있던 GID가 사용자 데이터베이스의 GID가 아닌 경우 다른 GID 세트로 끝날 수 있습니다.

목록을 있는 그대로 재설정하려면 또 다른 옵션은 의 도움으로 목록을 전달하는 것입니다. 예를 들어 perl(with) 와 동일한 변수가 있습니다 $UID. 단, gid 에는 추가 gid에 대한 정보도 포함되어 있습니다. 자체):$GID$EGIDzsh-MEnglishnice

run_with_nice() (
  exec perl -MEnglish -e '
    exec qw(sudo perl -MEnglish -MPOSIX=nice -e), qq(
    nice(shift\@ARGV);
    \$GID = "$GID"; \$EGID = "$EGID"; \$UID = $UID; \$EUID = $EUID;
    exec \@ARGV), "--", @ARGV' -- "$@"
)

그런 다음 다음을 실행하십시오.

$ run_with_nice -20 ps -o pid,user,group,nice,args
    PID USER     GROUP     NI COMMAND
   6955 chazelas chazelas -20 ps -o pid,user,group,nice,args

또는 귀하의 경우:

run_with_nice -20 bash ./myscript.sh

이 경우, 선호도를 변경하는 또 다른 방법은 renice반대 방법을 사용하는 것입니다. 하지만 매개변수 처리는 이식성이 매우 낮고(내 경험상 일반적으로 문서화되지 않음) 일부 사람들은 숫자를 다음과 같이 취급합니다. deltas , 일부는 새로운 값입니다.

sh -c 'sudo renice -n -20 -p "$$" && exec bash ./myscript.sh'

프로세스가 얼마나 잘 실행되는지 변경한 다음 uids/gids 또는 프로세스를 변경하지 않고 sh동일한 프로세스에서 계속 실행됩니다 . 여기bashshreniceutil-linux 2.38.1 부터 ,세트-2020으로 줄이지 않는 것이 좋습니다좋아하든지 nice -n하든지 nice().

답변2

사용자 모드에서 스크립트의 친화성 변경을 사용할 수 있습니다 sudo renice. 그러면 스크립트의 친화성과 이후에 생성되는 모든 하위 프로세스가 변경됩니다(내 질문을 수정해 준 @StéphaneChazelas에게 감사드립니다).

-g(프로세스 그룹) 옵션을 참고하세요 renice. 스크립트가 이미 실행 중이므로 시작되었을 수 있는 모든 C++ 하위 프로세스에도 장점을 적용해야 합니다.

$ cat nicely
#! /bin/bash

for (( j = 0; j < 10; j++ )); do
    printf 'Pid %d nice %d\n' $$ $( nice )
    sleep 3
done

$ ./nicely & Pid=$!; sudo renice -n -14 -g "${Pid}"; wait
[1] 5665
Pid 5665 nice 0
[sudo] password for paul: Pid 5665 nice 0
Pid 5665 nice 0
*******Pid 5665 nice 0
 
5665 (process ID) old priority 0, new priority -14
Pid 5665 nice -14
...
Pid 5665 nice -14
[1]+  Done                    ./nicely
paul@paul-RV415-RV515 ~ $ 

관련 정보