Pertanyaan Bagaimana cara membuat manajer paket menunggu jika contoh APT lain berjalan?


Saya telah melihat banyak perangkat lunak seperti Update Manager dan Synaptic Package Manager, mereka menunggu jika beberapa program lain menggunakan /var/lib/dpkg/lock dan terkunci. Bagaimana kita bisa melakukan ini melalui Terminal? saya melihat apt-getManual tetapi tidak menemukan sesuatu yang berguna.


45
2018-05-05 13:09


asal


Anda dapat melakukan beberapa perintah apt-get. Seperti sudo apt-get install packagename && sudo apt-get update dan mereka akan terjadi secara otomatis setelah satu sama lain. - Alvar
Apakah ini tidak melakukan itu: sudo apt-get install packagename1 packagename2 packagename3  ? - Rinzwind


Jawaban:


Kamu dapat memakai itu aptdcon perintah Manpage icon untuk mengantri tugas-tugas manajer paket dengan berkomunikasi dengan aptdaemon daripada menggunakan apt-get secara langsung.

Jadi pada dasarnya Anda bisa melakukannya sudo aptdcon --install chromium-browser atau apa pun dan ketika perintah itu berjalan Anda dapat menjalankannya lagi tetapi menginstal paket-paket yang berbeda dan apt-daemon hanya akan mengantri mereka alih-alih menghapus kesalahan.

Ini sangat berguna jika Anda melakukan upgrade panjang atau sesuatu dan ingin terus menginstal paket atau jika Anda melakukan scripting sesuatu bersama dan ingin memastikan menginstal hal-hal akan lebih dapat diandalkan.


31
2017-12-22 20:55



Bisa aptdcon dijalankan sedemikian rupa sehingga menerima setiap permintaan sebagai apt-get -y tidak? - Noki
yes | aptdcon --hide-terminal --install "package" Hide Terminal diperlukan, kalau tidak, piping yes akan menyebabkan masalah. - whitehat101
Masalah dengan jawaban ini adalah membutuhkan instalasi aptdcon. Saya sedang mengerjakan skrip bootstrap yang melakukan pengaturan awal VPS, di mana proses latar belakang juga melakukan beberapa penyiapan awal. Saya tidak bisa menginstal aptdcon sampai aku bisa mengerjakan kunci itu. - Fake Name
@FakeName untuk konfigurasi server awal Anda mungkin ingin menggunakan cloud-init: cloudinit.readthedocs.io/en/latest - Jorge Castro
paket apa itu aptdcon di? - ctrl-alt-delor


Anda bisa membuatnya apt-get untuk belajar menunggu jika manajer perangkat lunak lain sedang berjalan. Sesuatu yang mirip dengan perilaku dari gips layar berikutnya:

enter image description here

Bagaimana saya membuatnya?

Saya membuat skrip baru yang disebut apt-get (bungkus untuk apt-get) di /usr/local/sbin direktori dengan kode bash berikut di dalam:

#!/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 "$@"

Jangan lupa untuk membuatnya bisa dieksekusi:

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

Sebelum menguji, periksa apakah semuanya baik-baik saja. Output dari which apt-get perintah harus sekarang /usr/local/sbin/apt-get. Alasannya adalah: secara default, /usr/local/sbin direktori ditempatkan sebelumnya /usr/bin direktori di pengguna atau root PATH.


40
2017-11-10 16:27



Itu benar-benar hit langsung ke pertanyaan saya. terima kasih :) - Ten-Coin
Bagaimana skrip Anda mengelola instance yang ditumpuk dari apt-get? Seperti, sebelum selesai saya meluncurkan 5 apt-get lagi? - Braiam
@Braiam Hormat saya, saya tidak tahu; Saya bukan penguji yang baik. Apakah Anda mengujinya? Jika masalah muncul, skrip dapat ditingkatkan dengan membuat kunci baru dengan stempel waktu saat instance baru skrip dimulai (hanya contoh - ada juga banyak cara lain). - Radu Rădeanu
Wow! fasih. bekerja seperti pesona dengan semua yang telah saya lempar sejauh ini! Dua jempol ... ini seharusnya hanya menjadi bagian dari paket: D - Eric
Itu sempurna! Saya memiliki masalah di mana saya menggunakan cloudinit AWS untuk menginstal paket di server baru, tetapi Ubuntu melakukan beberapa apt barang di boot, jadi saya dpkg perintah gagal karena dpkg db terkunci. Saya telah menempatkan liner satu ini di cloudinit userdata saya: while fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 1; done; dpkg -i package.deb dan itu bekerja dengan baik. - Volodymyr Smotesko


Terlepas dari yang sudah jelas &&, Anda mungkin mencari aptdcon. Alat ini mampu mendeteksi instance apt lainnya dan menunggu mereka selesai:

sudo aptdcon --safe-upgrade
[/] 11% Menunggu manajer perangkat lunak lain berhenti Menunggu kecakapan

(Saya menjalankan kecerdasan di tempat lain)

Keuntungan dari alat ini adalah Anda dapat menyimpan beberapa tindakan secara berurutan tanpa mengkhawatirkan apa yang akan Anda lakukan selanjutnya. aptdcon sangat ideal untuk skrip tanpa pengawasan, dan instalasi GUI, karena Anda dapat membiarkan alat berjalan di latar belakang untuk tidak memblokir frontend Anda.

Operasi didukung oleh aptdcon adalah:

  • --refresh, -c: Ini setara dengan apt-get update. Ini memperbarui daftar paket Anda.
  • --install, --remove, --upgrade, --purge, --downgrade. Masing-masing dari mereka melakukan apa yang dikatakan nama mereka. Nama paket (s) adalah wajib. -i, -r, -u, -p: ini adalah opsi singkat untuk semua kecuali downgrade, yang tidak memilikinya.
  • --safe-upgrade, --full-upgrade adalah rekan-rekan untuk apt-get's upgrade/dist-upgrade dan aptitude's safe-upgrade/full-upgrade. Ini tidak membutuhkan parameter.
  • Ada beberapa operasi lain, yang dapat ditemukan di manual. Namun, ini adalah yang paling sering digunakan oleh pengguna yang tertarik aptd. Ada pilihan yang tumpang tindih dengan apa apt-key, apt-cache, dpkg melakukan.

apt-get itu sendiri tidak mendukung metode tersebut (untuk menunggu contoh lain dari apt), jadi aptdcon adalah solusi pilihan untuk manajer paket GUI: USC menggunakan aptd sebagai back-end, sama seperti Synaptic. Solusi lainnya adalah packagekit, tetapi tidak mendukung fungsi yang Anda cari (belum).


20
2017-11-09 12:19



aptdcon --install /path/to/pgk.deb Bekerja seperti dpkg -i, meskipun saya tidak dapat menemukan ini secara eksplisit disebutkan dalam manual. - whitehat101
Bisakah saya menggunakan ini di post-install script dalam satu paket? - Nelson Teixeira
@NelsonTeixeira mengapa Anda menggunakan ini di skrip ppst-install? Jika post-install sedang dieksekusi tentu saja sudah berjalan. - Braiam
Saya ingin membuat postinstall menginstal beberapa paket khusus yang tidak ada dalam repositori. Apakah ini mungkin? Saya akan memasukkan mereka dalam paket dan kemudian skrip akan menginstalnya setelah instalasi selesai. - Nelson Teixeira
@NelsonTeixeira lagi, mengapa itu perlu? Skrip post-install hanya berjalan ketika ada instalasi paket. Saya menyarankan Anda untuk ajukan pertanyaan sebagai gantinya dan jelaskan kasus Anda dengan lebih detail. - Braiam


Pendekatan yang sangat sederhana adalah naskah yang menunggu kunci tidak terbuka. Sebut saja waitforapt dan tempelkan /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

Kemudian jalankan saja sudo waitforapt && sudo apt-get install whatever. Anda bisa menambahkan pengecualian ke dalam sudoers untuk memungkinkan Anda menjalankannya tanpa perlu kata sandi (Anda akan membutuhkannya untuk apt-get jadi tidak ada keuntungan besar).

Sayangnya ini tidak mengantre hal. Mengingat bahwa beberapa operasi apt bersifat interaktif ("Apakah Anda yakin ingin menghapus semua paket itu ?!"), saya tidak bisa melihat dengan baik di sini ...


16
2017-11-09 12:50



mungkin -y berasumsi ya untuk semua operasi? - Braiam
Terima kasih. Saya pikir saya bisa menggunakannya dengan lebih baik jika saya menggunakan bantuan alias. - Ten-Coin
Tidak yakin -y memang diinginkan. - Oli♦
Saya tidak berpikir Anda ingin membungkus sudo fuser di [[ $(...) ]]. Ini mengembalikan kode keluar nol ketika file sedang diakses sehingga seharusnya cukup. - kiri
Saya menemukan solusi berikut ini menjadi lebih lengkap, karena ada beberapa kunci yang terlibat ketika bekerja dengan 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 Kiessling


Anda bisa menggunakan teknik polling:

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

3
2017-12-09 22:29



lebih baik digunakan inotify - ctrl-alt-delor


Saya membuat skrip yang melakukan ini:

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

Simpan di atas ke dalam /usr/local/sbin/apt-get. apt-get kemudian akan menunggu jika instance lain sudah berjalan.

Atau, simpan sebagai /usr/local/sbin/apt-wait, contoh penggunaan:

apt-wait && aptitude

yang akan berjalan aptitude setelah proses saat ini memegang kunci telah keluar.

Contoh run:

  1. Pertama, sebuah apt-get perintah dijalankan, misalnya:

    $ sudo apt-get remove some_package
    
  2. Kemudian, di terminal lain, perintah lain dijalankan:

    $ sudo apt-get install some_other_package
    

    Ini akan menunggu perintah pertama selesai lalu jalankan. Output sambil menunggu:

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

3
2018-01-19 04:32



lebih baik digunakan inotify - ctrl-alt-delor


Sayangnya fuser tidak melakukan banyak hal untuk Anda ketika Anda berjalan di wadah namespace unprivileged seperti lxc.

Juga, aptdcon tidak diinstal secara default (setidaknya pada 18.04) dan latar belakang tugas Anda dalam antrian sehingga Anda kehilangan serialisasi. Ini tidak dapat diatasi, tetapi itu berarti otomasi Anda perlu memiliki beberapa cara untuk menghindari kesalahan kawanan di apt ketika menginstal aptdcon, dan Anda harus memiliki semacam loop menunggu untuk apa pun yang Anda butuhkan untuk bersambung setelah menginstal paket melalui aptdcon kecuali ada semacam bendera untuk itu.

Apa pekerjaan itu berduyun-duyun. Ini juga harus bekerja di atas NFS dll karena menggunakan penguncian sistem file dengan cara yang sama apt, hanya dengan parameter detik -w itu akan menunggu pada kunci Anda, bukan melempar kesalahan.

Jadi mengikuti model pembungkus, tambahkan ini sebagai apt-get di / usr / local / bin / dan bagikan.

Ini juga memiliki manfaat membatasi IO dengan tidak membolehkan paralelisme pada apt sehingga Anda dapat membiarkan cron memicu pembaruan pada tengah malam di mana saja tanpa merusak disk.

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

Permintaan fitur yang sangat bagus dan sederhana untuk apt-get adalah flag -w untuk beralih ke kunci pemblokiran / tunggu.


2
2017-09-07 18:02





Satu-liner berdasarkan Jawaban Oli:

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

0
2018-02-27 06:55