Başka bir APT örneği çalışıyorsa, paket yöneticisi nasıl bekletilir?


50

Update Manager ve Synaptic Package Manager gibi birçok yazılım gördüm, başka bir program kullanıyorsa /var/lib/dpkg/lockve kilitliyse bekliyorlar. Terminal üzerinden bunu nasıl yapabiliriz? apt-getEl kitabını gördüm ama işe yarar bir şey bulamadım.


pek çok apt-get komutunu yapabilirsiniz. Gibi sudo apt-get install packagename && sudo apt-get updateve birbiri ardına otomatik olacak.
Alvar

1
Bu yapmaz mı sudo apt-get install packagename1 packagename2 packagename3 ?
Rinzwind

(Bkz. Unix.stackexchange.com/questions/463498/… , Ubuntu 18.04 ve üzeri sürümlerde bitirmek için uygun başlatma süresi beklemeye çalıştığınız özel bir durum varsa)
Anon

Yanıtlar:


35

Apt-get işlevini kullanmak yerine aptdaemon ile iletişim kurarak paket yöneticisi görevlerini sıraya koymak için aptdconkomutuManpage simgesi kullanabilirsiniz .

Yani temelde ne yapabilirseniz sudo aptdcon --install chromium-browserveya ne yaparsanız yapın ve bu komut çalışırken onu tekrar çalıştırabilirsiniz ancak farklı paketler kurun ve apt-daemon hata yapmak yerine sıraya alınacak.

Bu, özellikle uzun bir yükseltme yapıyorsanız veya bir şey yapıyorsanız ve paketleri yüklemeye devam etmek istiyorsanız veya birlikte bir şeyler yazıyorsanız ve bir şeylerin yüklenmesinin daha güvenilir olacağından emin olmak istiyorsanız kullanışlıdır.


4
Can aptdcono kadar istemleri kabul ettiği böyle çalıştırılabilir apt-get -ymi?
Noki,

4
yes | aptdcon --hide-terminal --install "package"Terminali Gizle gereklidir, aksi takdirde borular yessorunlara yol açacaktır.
whitehat101

1
Bu sorunun cevabı kurulum gerektiriyor olmasıdır aptdcon. Bir arka plan işleminin de başlangıç ​​ayarını yaptığı VPS'nin ilk kurulumunu yapan bir önyükleme betiği üzerinde çalışıyorum. aptdconKilidin etrafında çalışana kadar kurulum yapamam.
Sahte Adı

2
: İlk sunucu yapılandırması için @FakeName muhtemelen bulut-init kullanmak istiyorum cloudinit.readthedocs.io/en/latest
Jorge Castro

1
hangi paket aptdconiçinde
ctrl-alt-delor

45

Sen yapabilir apt-getbaşka bir yazılım yöneticisi çalışıyorsa beklemek öğrenmek için. Bir sonraki ekrandan gelen davranışa benzer bir şey:

görüntü tanımını buraya girin

Nasıl yaptım?

İçinde aşağıdaki bash kodunun bulunduğu dizinde apt-get(wrapper for apt-get) adında yeni bir komut dosyası oluşturdum /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 "$@"

Çalıştırılabilir hale getirmeyi unutmayın:

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

Teste başlamadan önce her şeyin yolunda olup olmadığını kontrol edin. which apt-getKomutun çıktısı şimdi olmalı /usr/local/sbin/apt-get. Nedeni şudur: Varsayılan olarak, dizin kullanıcı veya kök dizinindeki dizinin /usr/local/sbinönüne yerleştirilir ./usr/binPATH


bu gerçekten sorumu doğrudan etkiliyor. thanks :)
rɑːdʒɑ 10:13

2
Komut dosyanız, apt-get öğesinin yığılmış örneklerini nasıl yönetir? Mesela, bitirmeden önce 5 tane daha apt-get?
Braiam

@ Braiam Saygılarımızla, bilmiyorum; Ben iyi bir testçi değilim. Test ettin mi? Sorunlar ortaya çıkarsa, komut dosyasının yeni bir örneği başladığında komut dosyası zaman damgalı yeni bir kilit oluşturarak iyileştirilebilir (yalnızca bir örnek - ayrıca başka yollar da vardır).
Radu Rădeanu

Vaov! dokunaklısıydı. Şimdiye kadar attığım her şeyi bir çekicilik gibi çalışıyor! İki başparmak yukarıya ... bu sadece paketin bir parçası olmalı: D
Eric

2
Bu mükemmel! Paketleri yeni bir sunucuya kurmak için AWS cloudinit kullandığım yerde sorun yaşadım, ancak Ubuntu aptönyüklemede bazı şeyler yapıyor, bu yüzden komutum dpkgkilitli dpkg db nedeniyle başarısız oldu. Bu tek astarı cloudinit kullanıcı verilerime koydum: while fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 1; done; dpkg -i package.debharika çalışıyor.
Volodymyr Smotesko

20

Belli ki dışında, &&arıyor olabilirsiniz aptdcon. Bu araç diğer apt örneklerini algılayabilir ve bitmelerini bekleyebilir:

sudo aptdcon - güvenli yükseltme
[/] 11% Diğer yazılım yöneticilerinin bırakılmasını bekliyor Yetenek bekliyorum

(Başka bir yerde yetenek çalıştırıyorum)

Bu aracın avantajı, daha sonra yapacaklarınızdan endişe etmeden art arda birkaç işlemi stoklayabilmenizdir. aptdconKatılımsız komut dosyaları ve GUI kurulumu için idealdir, çünkü aracın ön uçlarınızı engellemeyecek şekilde arka planda çalışmasına izin verebilirsiniz.

Tarafından desteklenen işlemler aptdcon:

  • --refresh, -c: Bu eşdeğerdir apt-get update. Paket listenizi günceller.
  • --install, --remove, --upgrade, --purge, --downgrade. Her biri isminin dediği gibi yapar. Paketlerin adı zorunludur. -i, -r, -u, -p: Bu bir yok hepsi hariç downgrade, kısa seçeneklerdir.
  • --safe-upgrade, --full-upgradeMuadilleri için olan apt-getsitesindeki upgrade/ dist-upgradeve aptitudesitesindeki safe-upgrade/ full-upgrade. Bunların parametrelere ihtiyacı yok.
  • Kılavuzda bulunabilecek başka işlemler de var. Ancak, bunlar ilgilenen kullanıcılar tarafından en çok kullanılanlardır aptd. Ne örtüşen seçenek vardır apt-key, apt-cache, dpkgyap.

apt-getkendisi bu tarz yöntemleri desteklemiyor (diğer apt örneklerini beklemek için), aptdconGUI'nin paket yöneticilerine tercih edilen çözüm de: USC, aptdSynaptic ile aynı şekilde arka uç kullanıyor . Diğer çözüm ise packagekit, (henüz) aradığınız işlevi desteklemiyor.


1
aptdcon --install /path/to/pgk.debdpkg -iBu, kılavuzda açıkça belirtilenleri bulamamama rağmen, gibi çalışır .
whitehat101

Bunu bir pakette yükleme sonrası komut dosyasında kullanabilir miyim?
Nelson Teixeira

@NelsonTeixeira ppst-install komut dosyasında neden bunu kullandınız? Eğer yükleme sonrası çalıştırılıyorsa, kesinlikle apt çalışıyor.
Braiam

Postinstall'ın depoda olmayan bazı özel paketleri kurmasını istiyorum. Mümkün mü ? Onları pakete eklerdim ve kurulum bittikten sonra script onları yüklerdi.
Nelson Teixeira

@NelsonTeixeira tekrar, neden gerekli olacak? Yükleme sonrası komut dosyaları yalnızca bir paket yüklemesi olduğunda çalışır. Bunun yerine bir soru sormanızı ve durumunuzu daha ayrıntılı olarak açıklamanızı öneririm .
Braiam

18

Çok basit bir yaklaşım kilidin açılmamasını bekleyen bir senaryo olacaktır. Arayalım waitforaptve sokalım /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

O zaman sadece koş sudo waitforapt && sudo apt-get install whatever. sudoersŞifreye gerek kalmadan çalıştırmanıza izin vermek için istisnalar ekleyebilirsiniz (bunun için ihtiyacınız olacak, bu apt-getyüzden büyük bir kazanç yoktur).

Ne yazık ki bu işleri sıraya sokmaz. Bazı işlemlerin etkileşimli olduğu göz önüne alındığında ("Tüm bu paketleri kaldırmak istediğinizden emin misiniz ?!"), bunun için iyi bir yol göremiyorum ...


belki -ytüm operasyonlar için evet kabul etmek?
Braiam

Teşekkür ederim. Diğer ad yardımını kullanırsam daha iyi kullanabileceğimi düşünüyorum.
rʒɑdʒɑ

3
Emin -yolmasa da arzu edilir.
Oli

1
Sana sarmak istiyorum sanmıyorum sudo fuseriçinde [[ $(...) ]]. Yeterli olması için dosyaya erişilirken sıfır bir çıkış kodu döndürür.
kiri

4
Apt-get ile çalışırken birkaç kilit bulunduğundan, aşağıdaki çözümü daha eksiksiz buldum: 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

Yoklama tekniği kullanabilirsiniz:

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

daha iyi kullanmakinotify
ctrl-alt-delor

3

Bunu yapan bir komut dosyası yaptım:

#!/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

Yukarıdakileri saklayın /usr/local/sbin/apt-get. apt-getZaten başka bir örnek çalışıyorsa bekleyecek.

Alternatif olarak /usr/local/sbin/apt-wait, örnek kullanım olarak kaydedin :

apt-wait && aptitude

Bu aptitude, kilidi tutan geçerli işlemden çıktıktan sonra çalışacaktır .

Örnek çalışma:

  1. İlk önce bir apt-getkomut çalıştırılır, örneğin:

    $ sudo apt-get remove some_package
    
  2. Ardından, başka bir terminalde, başka bir komut çalıştırılır:

    $ sudo apt-get install some_other_package
    

    İlk komutun bitmesini ve sonra çalışmasını bekleyecektir. Beklerken çıktı:

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

1
daha iyi kullanmakinotify
ctrl-alt-delor

3

Maalesef kaynaştırıcı, lxc gibi farklı ayrıcalıklı ad alanı kaplarında çalışırken sizin için fazla bir şey yapmaz.

Ayrıca, aptdcon varsayılan olarak kurulmaz (en azından 18.04'te) ve serisini sıraya sokar, böylece serileştirmeyi kaybedersiniz. Bu aşılmaz bir şey değildir, ancak bu otomasyonun aptdcon'u kurarken uygunlukta sürü hatalarını önlemek için bir yolunun olması gerektiği anlamına gelir ve aptdcon aracılığıyla paketleri kurduktan sonra seri hale getirmek için ihtiyacınız olan herhangi bir şey için bir tür bekleme döngülerine sahip olmanız gerekir. Zaten bunun için bir çeşit bayrak yoksa.

İşe yarayan sürü. Bu aynı zamanda NFS vb üzerinde çalışmalıdır çünkü dosya sistemi kilitlemeyi apt yöntemiyle aynı şekilde kullanır, sadece -w seconds parametresiyle hata yapmak yerine kilidinizde bekler.

Bu nedenle sarmalayıcı modelini izleyerek bunu / usr / local / bin / dizininde apt-get olarak ekleyin ve paylaşın.

Bu aynı zamanda IO'yu sınırlama avantajına sahiptir ve apt üzerinde paralelliğe izin vermeyerek cron güncellemelerini gece yarısı her yerde diski yenmeden tetiklemesini sağlayabilirsiniz.

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

Apt-get için çok hoş ve basit bir özellik isteği bir engelleme / bekleme kilidine geçmek için bir -w bayrağı olacaktır.


apt fcntl kullanır, sürü kullanmaz, bu yüzden işe yaramaz. askubuntu.com/questions/1077215/…
Andy

Bu mükemmel çalışır ve fuserbirçok cevapta gösterildiği gibi kullanmaktan daha iyi bir seçenektir, çünkü fuserhala kilidi izlemek ve kilidi tekrar yakalamak olan hedef işlem arasındaki yarış koşullarına eğilimlidir. İle flockkilit edinilen ve daha sonra bu süre içinde kilidi kaybetme hiçbir zaman bırakır böylece hedef sürecine geçirilir.
jrudolph

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.