설치 스크립트 기간 동안 sudo의 시간 초과를 일시적으로 증가


22

로 모든 것을 실행해야하지 나는 소프트웨어의 무리를 설치하는 스크립트를 작성하려고 해요 그리고 내가 좋아하는 것 root내가 암호를 프롬프트 할 수 다음에 대해 가고 싶은, 그래서 설치, 사용 sudo또는 su내가 필요할 때 특권을 얻습니다.

나는하고 있었는데 sudo -v스크립트의 시작 부분에 암호 입력을 요구하도록하고 다만 일반적으로 나중에는 sudo를 사용하여. 제한 시간을 초과하는 단일 설치에 도달 할 때까지이 방법이 효과적입니다.

오히려 시간 초과를 영구적으로 늘릴 필요는 없습니다. 현재 세션에 대해서만 sudo의 시간 초과를 늘릴 수있는 방법이 있습니까?

답변:


8

"sudo -v"를 주기적으로 실행하기 위해 백그라운드에서 실행되는 루프를 설정할 수 있습니다. 물론 스크립트가 종료 될 때 루프가 깨끗하게 종료되도록해야합니다. 따라서 두 프로세스 간에는 어떤 유형의 커뮤니케이션이 있어야합니다. tmp 파일은 이것에 적합하며 스크립트가 실행 된 후에도 쉽게 정리할 수 있습니다. (어쨌든 설치 스크립트는 일반적으로이 작업을 수행합니다.)

예를 들어 이것을 사용하려면 'echo'문을 제거하십시오.

#!/bin/bash
log=running_setup.txt
sudo_stat=sudo_status.txt

echo "========= running script $$ ========"
echo $$ >> $sudo_stat
trap 'rm -f $sudo_stat >/dev/null 2>&1' 0
trap "exit 2" 1 2 3 15

sudo_me() {
 while [ -f $sudo_stat ]; do
  echo "checking $$ ...$(date)"
  sudo -v
  sleep 5
 done &
}


echo "=setting up sudo heartbeat="
sudo -v
sudo_me

echo "=running setup=" | tee $log
while [ -f $log ]
do
 echo "running setup $$ ...$(date) ===" | tee -a $log
 sleep 2
done

# finish sudo loop
rm $sudo_stat

그러면 다음과 같은 내용을 볼 수 있습니다. (참고 : pid는 tmp 파일에 저장되므로 쉽게 죽일 수 있습니다.

$ ./do_it.sh
========= running script 6776 ========
=setting up sudo heartbeat=
[sudo] password for user: 
=running setup=
checking 6776 ...Wed May  4 16:31:47 PDT 2011
running setup 6776 ...Wed May  4 16:31:48 PDT 2011 ===
running setup 6776 ...Wed May  4 16:31:50 PDT 2011 ===
running setup 6776 ...Wed May  4 16:31:52 PDT 2011 ===
checking 6776 ...Wed May  4 16:31:53 PDT 2011
running setup 6776 ...Wed May  4 16:31:54 PDT 2011 ===
<ctrl-c>  (cleans up files, then exits)

9

나는 michael_n의 대답을 좋아했지만 임시 파일을 사용하지 않는 가장 비합리적인 욕구가있었습니다. 아마도 이것은 약간의 관점을 제공 할 수 있습니다.

내 해결책은 다음과 같습니다.

#!/bin/bash
function sudo_ping() {
    if [[ ! -z $SUDO_PID ]]; then
        if [[ $1 -eq stop ]]; then
            echo "Stopping sudo ping in PID = $SUDO_PID"
            kill $SUDO_PID
            return
        else
            echo "Already sudo pinging in PID = $SUDO_PID"
            return
        fi
    fi

    echo "Starting background sudo ping..."
    sudo -v
    if [[ $? -eq 1 ]]; then
        echo "Oops, wrong password."
        return
    fi
    sudo echo "ok"

    while true; do
        echo 'Sudo ping!'
        sudo -v
        sleep 1
    done &
    SUDO_PID=$!
    sudo echo "Sudo pinging in PID = $SUDO_PID"

    # Make sure we don't orphan our pinger
    trap "sudo_ping stop" 0
    trap "exit 2" 1 2 3 15
}

sudo_ping
sleep 5
echo "Goodbye!"

다시 말하지만,의 echo외부는 ...

$ ./sudoping.sh 
Starting background sudo ping...
Password:
ok  
Sudo ping!
Sudo pinging in PID = 47531
Sudo ping!
Sudo ping!
Sudo ping!
Sudo ping!
Goodbye!
Stopping sudo ping in PID = 47531

다시 ctrl-c도 작동합니다 ...

$ ./sudoping.sh 
Starting background sudo ping...
ok  
Sudo ping!
Sudo pinging in PID = 47599
Sudo ping!
^CStopping sudo ping in PID = 47599

6
그리고 더 간결 솔루션 : gist.github.com/3118588
그레고리 퍼킨스

1000 개 이상의 공감대가없는 이유는 무엇입니까 ??? 간결한 버전은 훌륭합니다. (그러나 더 좋은 예가 도움이 될 것이라고 생각합니다.)
Monica Cellio 용 MountainX

3

요점을 기반으로 간결하고 깨끗한 버전을 만들었습니다.

# Prevent sudo timeout
sudo -v # ask for sudo password up-front
while true; do
  # Update user's timestamp without running a command
  sudo -nv; sleep 1m
  # Exit when the parent process is not running any more. In fact this loop
  # would be killed anyway after being an orphan(when the parent process
  # exits). But this ensures that and probably exit sooner.
  kill -0 $$ 2>/dev/null || exit
done &

sudo -K쉘 스크립트의 다른 곳에서 호출 하면 버전이 sudo: a password is required매분 stderr 에게 소리 지르기 때문에 요지 버전이 더 좋을 것이라고 생각합니다 .
Rockallite

@ Rockallite 내 연결된 요점을 의미합니까? 그들은 실제로 동일합니다.
Bohr

0

sudo매뉴얼 페이지 에 따르면 :

   -v          If given the -v (validate) option, sudo will update the user's time stamp,
               prompting for the user's password if necessary.  This extends the sudo timeout for
               another 15 minutes (or whatever the timeout is set to in sudoers) but does not run
               a command.

따라서 sudo -v세션의 유효성을 검사하기 위해 설정 스크립트의 더 많은 지점 을 추가하면 (그리고 시작 부분뿐만 아니라) 시간 초과가 증가하기 때문에 원하는 것을 얻을 수 있다고 생각합니다. 시간 초과에 도달했습니다). 유일한 문제는 스크립트에 시간 초과보다 많은 시간이 걸리는 명령이있는 경우입니다 (따라서 바로 다음에 유효성 검사를 한 경우에도 다른 유효성 검사를 완료하기 전에 시간 만료가 만료 됨)지만 이는 매우 구체적인 경우입니다.

발생하는 것은 sudo시간 초과를 늘리지 sudo -v않고 명령을 실행하지 않기 때문에 sudo -v더 많은 시간을 사용 하여 세션의 유효성을 검사해야합니다.


네, 고마워요. 문제는 내 sudo 시간 초과가 5 분에 가깝다는 것입니다.
Arelius

흠. 잘. 시간 초과를 늘리는 것 외에는 할 일이별로 없습니다. 일시적으로 설정할 수있는 방법이 없습니다.
coredump

0

상의 기본 취지 에 의해 제공 그레고리 퍼킨스 와 내 경험은, 여기 내 한 줄입니다 :

trap "exit" INT TERM; trap "kill 0" EXIT; sudo -v || exit $?; sleep 1; while true; do sleep 60; sudo -nv; done 2>/dev/null &

또는

trap "exit" INT TERM
trap "kill 0" EXIT
sudo -v || exit $?
sleep 1
while true; do
    sleep 60
    sudo -nv
done 2>/dev/null &

설명

  • trap "exit" INT TERM; trap "kill 0" EXIT: 종료 또는 SIGINT / SIGTERM에서 전체 프로세스 트리가 중단됩니다.

  • sudo -v || exit $?: 암호를 미리 요청하고 보안 자격 증명을 캐시하지만 명령을 실행하지 마십시오. 비밀번호가 올바르지 않으면 sudo에서 리턴 한 코드로 종료하십시오.

  • sleep 1: 보안 자격 증명이 효과적으로 저장되도록 약간 지연시킵니다. 다음 sudo가 너무 빨리 실행되면 자격 증명이 아직 저장되지 않아 알 수 없으므로 암호를 다시 묻습니다.

  • while true; do sleep 60; sudo -nv; done 2>/dev/null &: 기존 sudo 보안 신임 정보를 반복적으로 업데이트하십시오. 이 버전은 연결된 요지 중 하나와 다릅니다 . sleep 60먼저 실행 한 다음을 실행하십시오 sudo -nv.

    • &운영자는 전체두고 while자식 프로세스로 실행 배경으로 루프.

    • 2>/dev/null의 열려진 리디렉션 while루프 내부에 명령에 의해 발생 된 에러 메시지가 폐기 될 수 있도록, 공극에 루프.

    • -n옵션을 사용 sudo하면 암호를 묻는 메시지가 표시되지 않지만 오류 메시지가 표시되고 암호가 필요한 경우 종료됩니다.

    • kill -0 "$$" || exit연결된 gist 에는 없습니다 . 처음 두 개가 trap작업을 수행 하기 때문 입니다. 부모 프로세스가 실행되고 있지 않다고 판단하기 전에 59 초 동안 잠을 자지 않아도됩니다!

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