#!/bin/bash
-# Copyright (C) 2014 Ian Kelling
+# I, Ian Kelling, follow the GNU license recommendations at
+# https://www.gnu.org/licenses/license-recommendations.en.html. They
+# recommend that small programs, < 300 lines, be licensed under the
+# Apache License 2.0. This file contains or is part of one or more small
+# programs. If a small program grows beyond 300 lines, I plan to switch
+# its license to GPL.
+
+# Copyright 2024 Ian Kelling
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
$s yum -y install "$@"
}
# package find
- pf() {
+ pfd() {
local s; [[ $EUID != 0 ]] && s=sudo
$s yum search "$@"
}
local s; [[ $EUID != 0 ]] && s=sudo
$s yum autoremove "$@"
}
+ # shellcheck disable=SC2120
pup() { # upgrade
local s; [[ $EUID != 0 ]] && s=sudo
$s yum -y distro-sync full "$@"
}
elif command -v apt-get &>/dev/null; then
+ plock-wait() {
+ local i
+ i=0
+ while fuser /var/lib/dpkg/lock &>/dev/null; do
+ sleep 1
+ i=$(( i+1 ))
+ if (( i > 300 )); then
+ echo "error: timed out waiting for /var/lib/dpkg/lock" >&2
+ return 1
+ fi
+ done
+ }
+ pcheck() {
+ for arg; do
+ if [[ $1 == -* ]]; then
+ shift
+ else
+ break
+ fi
+ done
+ if dpkg -s -- "$@" |& grep -Fx "Status: install ok installed" &>/dev/null; then
+ return 1
+ fi
+ return 0
+ }
pp() { # package policy
apt-cache policy $@
}
esac
}
pupdate() {
- local s f; [[ $EUID != 0 ]] && s=sudo
+ local now t s f cachetime limittime; [[ $EUID != 0 ]] && s=sudo
# update package list if its more than an 2 hours old
f=/var/cache/apt/pkgcache.bin
- if [[ ! -r $f ]] \
- || (( $(( $(date +%s) - $(stat -c %Y $f ) )) > 60*60*2 )); then
+ if [[ -r $f ]]; then
+ cachetime=$(stat -c %Y $f )
+ else
+ cachetime=0
+ fi
+ now=$(date +%s)
+ limittime=$(( now - 60*60*2 ))
+ for f in /etc/apt/sources.list /etc/apt/sources.list.d/*.list; do
+ if [[ -r $f ]]; then
+ t=$(stat -c %Y $f )
+ if (( t > limittime )); then
+ limittime=$t
+ fi
+ fi
+ done
+ if (( cachetime > limittime )); then
$s apt-get update
fi
}
pi() {
- if dpkg -s -- "$@" &>/dev/null; then
- return 0
- fi
- while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done
+ pcheck "$@" || return 0
pupdate
- local s; [[ $EUID != 0 ]] && s=sudo
- $s $PI_PREFIX apt-get -y --allow-downgrades install --purge --auto-remove "$@"
+ if [[ $- != *i* ]]; then
+ echo pi "$*"
+ fi
+ if [[ $EUID == 0 ]]; then
+ DEBIAN_FRONTEND=noninteractive apt-get -y install --purge --auto-remove "$@"
+ else
+ sudo DEBIAN_FRONTEND=noninteractive apt-get -y install --purge --auto-remove "$@"
+ fi
+
}
pi-nostart() {
- if dpkg -s -- "$@" &>/dev/null; then
- return 0
- fi
- while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done
+ local ret=
+ pcheck "$@" || return 0
+ plock-wait
pupdate
- local s; [[ $EUID != 0 ]] && s=sudo
local f=/usr/sbin/policy-rc.d
- $s dd of=$f <<EOF
+ if [[ $- != *i* ]]; then
+ echo pi-nostart "$@"
+ fi
+ if [[ $EUID == 0 ]]; then
+ dd of=$f status=none <<EOF
#!/bin/sh
exit 101
EOF
- $s chmod +x $f
- $s apt-get -y install --allow-downgrades --purge --auto-remove "$@"
- $s rm $f
+ chmod +x $f
+ DEBIAN_FRONTEND=noninteractive apt-get -y install --purge --auto-remove "$@" || ret=$?
+ rm $f
+ else
+ sudo dd of=$f status=none <<EOF
+#!/bin/sh
+exit 101
+EOF
+ sudo chmod +x $f
+ sudo DEBIAN_FRONTEND=noninteractive apt-get -y install --purge --auto-remove "$@" || ret=$?
+ sudo rm $f
+ fi
+ return $ret
}
- pf() {
+ # package find description
+ pfd() {
# package name and descriptions
apt-cache search "$@"
}
+ # package find file
pff() {
local s; [[ $EUID != 0 ]] && s=sudo
# nice aptitude search from emacs shell. package description width as
}
pu() {
local s; [[ $EUID != 0 ]] && s=sudo
- while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done
- $s apt-get -y remove --allow-downgrades --purge --auto-remove "$@"
+ local needed=false
+ for arg; do
+ if dpkg -s -- "$arg" &>/dev/null; then
+ needed=true
+ break
+ fi
+ done
+ $needed || return 0
+ plock-wait
+ $s apt-get -y remove --purge --auto-remove "$@"
# seems slightly redundant, but it removes more stuff sometimes.
- $s apt-get -y --allow-downgrades autoremove
+ $s apt-get -y autoremove
}
+ # shellcheck disable=SC2120
pup() { # upgrade
- while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done
+ plock-wait
pupdate
local s; [[ $EUID != 0 ]] && s=sudo
- $s apt-get -y dist-upgrade --allow-downgrades --purge --auto-remove "$@"
- $s apt-get -y autoremove --allow-downgrades
+ $s apt-get -y dist-upgrade --purge --auto-remove "$@"
+ $s apt-get -y autoremove
}
# package info
pl() {
fi
}
pfile() {
+ # -a = search all repos
+ local -a arg all
+ all=false
+ case $1 in
+ -a)
+ all=true
+ shift
+ ;;
+ esac
local file=$1
# ucfq can tell us about config files which are not tracked
# with apt-file. but, for at least a few files I tested
# if [[ $file == /* ]] && ! ucfq -w $file | grep ::: &>/dev/null; then
# ucfq $file
- if [[ $file == */* ]]; then
- apt-file find -x "$file"\$
+ if [[ $file == /* ]]; then
+ dpkg -S "$file"
else
- apt-file find -x /"$file"\$
- update-alternatives --list "$file" 2>/dev/null
+ if ! $all; then
+ arg=(--filter-origins "$(positive-origins)")
+ fi
+ if [[ $file == /* ]]; then
+ apt-file "${arg[@]}" find -x /"$file"\$
+ update-alternatives --list "$file" 2>/dev/null
+ else
+ apt-file "${arg[@]}" find -x "$file"\$
+ fi
fi
}
pkgfiles() {
if dpkg -s "$1" &>/dev/null; then
- dpkg-query -L $1
+ dpkg-query -L $1 | while read -r l; do [[ -f $l ]] && printf "%s\n" "$l"; done
else
apt-file -x list "^$1$"
fi
pi() {
pacaur -S --noconfirm --needed --noedit "$@"
}
- pf() {
+ pfd() {
pacaur -Ss "$@"
}
pu() {
aurex() {
p="$1"
aur='https://aur.archlinux.org'
- curl -s $aur/$(curl -s "$aur/rpc.php?type=info&arg=$p" \
- | jq -r .results.URLPath) | tar xz
+ curl -s $aur/"$(curl -s "$aur/rpc.php?type=info&arg=$p" \
+ | jq -r .results.URLPath)" | tar xz
cd "$p"
}
pmirror() {
local s; [[ $EUID != 0 ]] && s=sudo
- local x=$(mktemp)
+ local x
+ x=$(mktemp)
curl -s "https://www.archlinux.org/mirrorlist/\
?country=US&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on" \
| sed -r 's/^[ #]*(Server *=)/\1/' > $x
rm $x
fi
}
+ # shellcheck disable=SC2120
pup() { # upgrade
local s; [[ $EUID != 0 ]] && s=sudo
# file_time + 24 hours > current_time