다른 APT 인스턴스가 실행 중일 때 패키지 관리자를 대기 상태로 만드는 방법은 무엇입니까?


50

Update Manager 및 Synaptic Package Manager와 같은 많은 소프트웨어를 보았습니다. 다른 프로그램에서를 사용 /var/lib/dpkg/lock중이고 잠겨 있으면 기다립니다 . 터미널을 통해 어떻게 할 수 있습니까? 나는 apt-get매뉴얼을 보았지만 유용한 것을 찾지 못했습니다.


잘 당신은 여러 apt-get 명령을 할 수 있습니다. 서로 좋아 sudo apt-get install packagename && sudo apt-get update하고 자동으로 발생합니다.
Alvar

1
이 작업을 수행하지 sudo apt-get install packagename1 packagename2 packagename3 않습니까?
Rinzwind

( Ubuntu 18.04 이상에서 부팅 시간이 끝나기 를 기다리는 특수한 경우 unix.stackexchange.com/questions/463498/… 참조 )
Anon

답변:


35

apt-get을 직접 사용하는 대신 aptdaemon과 통신 하여 aptdcon명령맨 페이지 아이콘 을 사용 하여 패키지 관리자 태스크를 큐에 넣을 수 있습니다.

기본적으로 당신은 sudo aptdcon --install chromium-browser무엇이든 할 수 있고 그 명령이 실행되는 동안 다시 실행할 수는 있지만 다른 패키지를 설치하면 apt-daemon은 오류 대신 대기열에 넣습니다.

이것은 긴 업그레이드 나 무언가를하고 패키지를 계속 설치하고 싶거나 함께 스크립팅하고 설치의 안정성을 높이고 자 할 때 특히 유용합니다.


4
aptdcon프롬프트를 수락하도록 실행할 수 있습니까 apt-get -y?
Noki

4
yes | aptdcon --hide-terminal --install "package"터미널 숨기기가 필요합니다. 그렇지 않으면 배관으로 yes인해 문제가 발생할 수 있습니다.
whitehat101

1
이 답변의 문제점은 설치가 필요하다는 것 aptdcon입니다. 백그라운드 프로세스도 초기 설정을 수행하는 VPS의 초기 설정을 수행하는 부트 스트랩 스크립트를 작성 중입니다. aptdcon잠금 장치를 해결할 수있을 때까지 설치할 수 없습니다 .
가짜 이름

2
초기 서버 구성을위한 @FakeName 아마 cloud-init를 사용하고 싶을 것입니다 : cloudinit.readthedocs.io/en/latest
Jorge Castro

1
어떤 패키지 aptdcon에 있습니까?
ctrl-alt-delor

45

apt-get다른 소프트웨어 관리자가 실행중인 경우 대기하는 방법을 배울 수 있습니다 . 다음 화면 캐스트의 동작과 비슷한 내용 :

여기에 이미지 설명을 입력하십시오

어떻게 만들었습니까?

다음 bash 코드가 있는 디렉토리에 apt-get(wrapper for apt-get) 라는 새 스크립트를 만듭니다 /usr/local/sbin.

#!/bin/bash

i=0
tput sc
while fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do
    case $(($i % 4)) in
        0 ) j="-" ;;
        1 ) j="\\" ;;
        2 ) j="|" ;;
        3 ) j="/" ;;
    esac
    tput rc
    echo -en "\r[$j] Waiting for other software managers to finish..." 
    sleep 0.5
    ((i=i+1))
done 

/usr/bin/apt-get "$@"

실행 파일로 만드는 것을 잊지 마십시오 :

sudo chmod +x /usr/local/sbin/apt-get

테스트하기 전에 모든 것이 정상인지 확인하십시오. which apt-get명령 의 출력은 이제되어야합니다 /usr/local/sbin/apt-get. 그 이유는 다음과 같습니다. 기본적으로 디렉토리는 user 또는 root의 디렉토리 /usr/local/sbin앞에 있습니다./usr/binPATH


그게 내 질문에 직접 맞았습니다. thanks :)
rɑːdʒɑ

2
스크립트는 apt-get의 누적 인스턴스를 어떻게 관리합니까? 마치기 전에 5 개의 apt-get을 추가로 시작합니까?
브라이 암

@Braiam 진심으로, 나는 모른다; 나는 좋은 테스터가 아닙니다. 테스트 했습니까? 문제가 발생하면 스크립트의 새 인스턴스가 시작될 때 타임 스탬프를 사용하여 새 잠금을 만들어 스크립트를 개선 할 수 있습니다 (예 : 다른 방법도 많이 있음).
Radu Rădeanu

와! 웅변. 내가 지금까지 던진 모든 것을 가진 매력처럼 작동합니다! 엄지 손가락 두 개 ... 이것은 패키지의 일부 여야합니다. : D
Eric

2
저건 완벽 해! AWS cloudinit를 사용하여 새 서버에 패키지를 설치하는 데 문제가 있었지만 Ubuntu는 apt부팅시 일부 작업을 수행하므로 dpkg잠긴 dpkg db로 인해 명령이 실패했습니다. 이 one-liner를 cloudinit 사용자 데이터에 넣었 while fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 1; done; dpkg -i package.deb습니다.
Volodymyr Smotesko

20

명백한 것 외에도 &&, 당신은 찾고 있을지도 모릅니다 aptdcon. 이 도구는 apt의 다른 인스턴스를 감지하고 완료 될 때까지 기다릴 수 있습니다.

sudo aptdcon-안전한 업그레이드
[/] 11 % 다른 소프트웨어 관리자가 종료하기를 기다리는 중 적성을 기다리는 중

(나는 다른 곳에서 적성을 달리고있다)

이 도구의 장점은 다음에 수행 할 작업에 대해 걱정하지 않고 여러 작업을 연속으로 저장할 수 있다는 것입니다. aptdcon프론트 엔드를 차단하지 않도록 백그라운드에서 도구를 실행할 수 있으므로 무인 스크립트 및 GUI 설치에 이상적입니다.

지원되는 작업 aptdcon은 다음과 같습니다.

  • --refresh, -c: 이것은와 같습니다 apt-get update. 패키지 목록을 업데이트합니다.
  • --install, --remove, --upgrade, --purge, --downgrade. 그들 각자는 그들의 이름이 말하는대로합니다. 패키지 이름은 필수입니다. -i, -r, -u, -p:이 하나가없는 외 모두 다운 그레이드에 대한 짧은 옵션이 있습니다.
  • --safe-upgrade, --full-upgrade대응 부에있는 apt-getupgrade/ dist-upgradeaptitudesafe-upgrade/이 full-upgrade. 이들은 매개 변수가 필요하지 않습니다.
  • 매뉴얼에서 찾을 수있는 몇 가지 다른 작업이 있습니다. 그러나에 관심이있는 사용자가 가장 많이 사용합니다 aptd. 무엇과 중복 옵션이 있습니다 apt-key, apt-cache, dpkg할 수는.

apt-get자체적으로는 이러한 방법을 지원하지 않으며 (다른 인스턴스의 인스턴스를 기다림) aptdconGUI 패키지 관리자에게 선호되는 솔루션이 있습니다. USC는 aptdSynaptic과 같은 백엔드로 사용합니다 . 다른 솔루션은입니다 packagekit.하지만 찾고있는 기능을 아직 지원하지 않습니다.


1
aptdcon --install /path/to/pgk.debdpkg -i매뉴얼에서 명시 적으로 언급 한 것을 찾을 수는 없지만 작동 합니다.
whitehat101

패키지의 설치 후 스크립트에서 이것을 사용할 수 있습니까?
Nelson Teixeira

@NelsonTeixeira 왜 ppst-install 스크립트에서 이것을 사용 하시겠습니까? 사후 설치가 실행되면 분명히 apt가 실행 중입니다.
Braiam

설치 후 저장소에없는 특수 패키지를 설치하고 싶습니다. 이게 가능해 ? 패키지에 포함시킨 다음 설치가 완료되면 스크립트가 설치합니다.
Nelson Teixeira

@NelsonTeixeira, 왜 필요할까요? 설치 후 스크립트는 패키지 설치가있을 때만 실행됩니다. 나는 당신이하는 것이 좋습니다 대신 질문을 더 세부 귀하의 케이스를 설명합니다.
Braiam

18

매우 간단한 방법은 잠금이 열리지 않기를 기다리는 스크립트입니다. 전화해서 waitforapt꽂아 봅시다 /usr/local/bin:

#!/bin/sh

while sudo fuser /var/{lib/{dpkg,apt/lists},cache/apt/archives}/lock >/dev/null 2>&1; do
   sleep 1
done

그런 다음 실행하십시오 sudo waitforapt && sudo apt-get install whatever. sudoers암호를 요구하지 않고 실행할 수 있도록 예외를 추가 할 수 있습니다 (필요 apt-get하므로 큰 이득이 아닙니다).

불행히도 이것은 대기하지 않습니다. apt의 작업 중 일부가 대화식이라는 점을 고려하면 ( "모든 패키지를 제거 하시겠습니까?!")이 문제를 해결하는 좋은 방법은 없습니다.


아마도 -y모든 작업에 대해 예라고 가정합니까?
브라이 암

감사합니다. 별칭 도움말을 사용하면 더 잘 사용할 수 있다고 생각합니다.
rɑːdʒɑ

3
확실 -y하지는 않지만 바람직합니다.
Oli

1
난 당신이 포장하려는 생각하지 않는다 sudo fuser[[ $(...) ]]. 파일에 액세스 할 때 제로 종료 코드를 리턴하므로 충분해야합니다.
kiri

4
apt-get으로 작업 할 때 몇 가지 잠금이 포함되어 있기 때문에 다음 솔루션이 더 완벽하다는 것을 알았습니다. while sudo fuser /var/lib/dpkg/lock /var/lib/apt/lists/lock /var/cache/apt/archives/lock >/dev/null 2>&1; do echo 'Waiting for release of dpkg/apt locks'; sleep 5; done; sudo apt-get -yy update
Manuel Kießling

3

폴링 기술을 사용할 수 있습니다.

$ time (while ps -opid= -C apt-get > /dev/null; do sleep 1; done); \
  apt-get -y install some-other-package

더 나은 사용법inotify
ctrl-alt-delor

3

나는 이것을하는 스크립트를 만들었다 :

#!/bin/bash

# File path to watch
LOCK_FILE='/var/lib/dpkg/lock'

# tput escape codes
cr="$(tput cr)"
clr_end="$(tput el)"
up_line="$(tput cuu 1)"

CLEAN(){
    # Cleans the last two lines of terminal output,
    # returns the cursor to the start of the first line
    # and exits with the specified value if not False

    echo -n "$cr$clr_end"
    echo
    echo -n "$cr$clr_end$up_line"
    if [[ ! "$1" == "False" ]]; then
        exit $1
    fi
}

_get_cmdline(){
    # Takes the LOCKED variable, expected to be output from `lsof`,
    # then gets the PID and command line from `/proc/$pid/cmdline`.
    #
    # It sets `$open_program` to a user friendly string of the above.

    pid="${LOCKED#p}"
    pid=`echo $pid | sed 's/[\n\r ].*//'`
    cmdline=()
    while IFS= read -d '' -r arg; do
        cmdline+=("$arg")
    done < "/proc/${pid}/cmdline"
    open_program="$pid : ${cmdline[@]}"
}

# Default starting value
i=0

# Checks if the file is locked, writing output to $FUSER
while LOCKED="$(lsof -F p "$LOCK_FILE" 2>/dev/null)" ; do
    # This will be true if it isn't the first run
    if [[ "$i" != 0 ]]; then
        case $(($i % 4)) in
            0 ) s='-'
                i=4
                _get_cmdline # Re-checks the command line each 4th iteration
            ;;
            1 ) s=\\ ;;
            2 ) s='|' ;;
            3 ) s='/' ;;
        esac
    else
        # Traps to clean up the printed text and cursor position
        trap "CLEAN False; trap - SIGINT ; kill -SIGINT $$" SIGINT
        trap 'CLEAN $((128+15))' SIGTERM
        trap 'CLEAN $((128+1))' SIGHUP
        trap 'CLEAN $((128+3))' SIGQUIT

        # Default starting character
        s='-'

        _get_cmdline
        echo -n "$save_cur"
    fi
    # Prints the 2nd line first so the cursor is at the end of the 1st line (looks nicer)
    echo
    echo -n "$cr$clr_end$open_program"
    echo -n "$up_line$res_cur$cr$clr_end[$s] Waiting for other package managers to finish..."
    #echo -en "$cr$clr_end[$s] Waiting for other package managers to finish..."
    #echo -en "\n$cr$clr_end$open_program$cr$up_line"
    ((i++))
    sleep 0.025
done

CLEAN False

# This allows saving the script under a different name (e.g. `apt-wait`)
# and running it. It only imitates `apt-get` if it was launched as such
if [[ "${0##*/}" == 'apt-get' ]]; then
    exec /usr/bin/apt-get "$@"
    exit $?
fi

위의를에 저장하십시오 /usr/local/sbin/apt-get. apt-get그런 다음 다른 인스턴스가 이미 실행중인 경우 기다립니다.

또는 /usr/local/sbin/apt-wait사용법 예로 저장하십시오 .

apt-wait && aptitude

aptitude잠금을 보유한 현재 프로세스가 종료 된 후에 실행됩니다 .

예제 실행 :

  1. 먼저 다음과 같은 apt-get명령이 실행됩니다.

    $ sudo apt-get remove some_package
    
  2. 그런 다음 다른 터미널에서 다른 명령이 실행됩니다.

    $ sudo apt-get install some_other_package
    

    첫 번째 명령이 완료되고 실행되기를 기다립니다. 기다리는 동안 출력 :

    [/] Waiting for other package managers to finish...
          28223 : /usr/bin/apt-get remove some_package
    

1
더 나은 사용법inotify
ctrl-alt-delor

3

불행히도 lxc와 같은 권한이없는 다른 네임 스페이스 컨테이너에서 실행할 때 퓨저는 많은 도움이되지 않습니다.

또한 aptdcon은 기본적으로 설치되어 있지 않으며 (최소한 18.04 이상) 작업을 대기열에 배치하므로 직렬화가 손실됩니다. 이것은 극복 할 수 없지만 aptdcon을 설치할 때 aptdcon을 설치할 때 자동으로 무리 오류를 피할 수있는 방법이 필요하다는 것을 의미하며 aptdcon을 통해 패키지를 설치 한 후 직렬화 해야하는 모든 것에 대해 일종의 대기 루프가 필요합니다 이미 어떤 종류의 깃발이 없다면.

작동하는 것은 무리입니다. 이것은 apt와 동일한 방식으로 파일 시스템 잠금을 사용하므로 NFS 등에서도 작동해야합니다. -w seconds 매개 변수 만 사용하면 오류를 발생시키는 대신 잠금을 기다립니다.

랩퍼 모델에 따라 / usr / local / bin /에 apt-get으로 추가하고 공유하십시오.

또한 apt에서 병렬 처리를 허용하지 않음으로써 IO를 제한하는 이점이 있으므로 디스크를 두드리지 않고 자정에 cron이 업데이트를 트리거 할 수 있습니다.

#!/bin/bash
exec /usr/bin/flock -w 900 -F --verbose /var/cache/apt/archives/lock /usr/bin/apt-get $@  

apt-get에 대한 매우 훌륭하고 간단한 기능 요청은 차단 / 대기 잠금으로 전환하기위한 -w 플래그입니다.


apt는 무리가 아닌 fcntl을 사용하므로 작동하지 않습니다. askubuntu.com/questions/1077215/…
Andy

이것은 잠금을 보는 것과 대상 프로세스가 잠금을 다시 잡는 것 사이의 경쟁 조건이 여전히 발생하기 fuser때문에 많은 답변에 표시된 것처럼 사용하는 것보다 완벽하게 작동하며 더 나은 옵션 fuser입니다. 으로 flock잠금을 획득 한 후 그 동안 잠금을 잃는에 대한 시간을 남기지 않습니다 때문에 대상 프로세스에 전달됩니다.
jrudolph

1

Oli의 답변을 기반으로 한 라이너 :

while sudo fuser /var/{lib/{dpkg,apt/lists},cache/apt/archives}/lock >/dev/null 2>&1; do sleep 1; done
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.