我正在尝试找出一种与发行版无关的方法来安装提供特定可执行文件或文件的包。我知道不可能做到如此完美,但我认为我有一些几乎足够好的东西,我希望也许有人有关于如何改进它的想法。
基本上我编写了一个脚本,它提供了围绕最常见的包管理器的抽象层:
commandAvailable() { command -v $1 &> /dev/null; }
if commandAvailable dnf; then
updatePackageInfo() { dnf check-update; }
searchPath() { dnf provides $1 2> /dev/null | grep ' : ' | head -1 | cut -d'.' -f1 | rev | cut -d'-' -f 2- | rev; }
searchBin() { searchPath {/bin,/sbin,/usr/bin/,/usr/sbin}/$1; }
install() { dnf install -y $@; }
elif commandAvailable yum; then
updatePackageInfo() { yum check-update; }
searchPath() { yum provides $1 2> /dev/null | grep ' : ' | head -1 | cut -d'.' -f1 | rev | cut -d'-' -f 2- | rev; }
searchBin() { searchPath {/bin,/sbin,/usr/bin/,/usr/sbin}/$1; }
install() { yum install -y $@; }
elif commandAvailable apt-get; then
updatePackageInfo() { apt-get update && if ! commandAvailable apt-file; then install apt-file; fi && apt-file update; }
searchPath() { apt-file search $1 | head -1 | cut -d':' -f1; }
searchBin() { searchPath {/bin,/sbin,/usr/bin/,/usr/sbin}/$1; }
install() { apt-get install -y $@; }
elif commandAvailable pacman; then
updatePackageInfo() { pacman -Sy && pacman -Fy; }
searchPath() { pacman -F $1 | head -1 | rev | cut -d' ' -f2 | rev; }
searchBin() { pacman -F $1 | grep -B 1 -P " (usr/bin|usr/sbin|bin|sbin)/$1" | head -1 | cut -d' ' -f1; }
install() { pacman -S --noconfirm $@; }
elif commandAvailable zypper; then
updatePackageInfo() { zypper refresh; }
searchPath() { zypper search -f $1 | grep " | package" | head -1 | tr -d ' ' | cut -d'|' -f2; }
searchBin() { searchPath {/bin,/sbin,/usr/bin/,/usr/sbin}/$1; }
install() { zypper --non-interactive install "$@"; }
elif commandAvailable emerge; then
updatePackageInfo() { emerge-webrsync -v && if ! commandAvailable e-file; then install app-portage/pfl; fi; }
searchPath() { e-file $1 | grep -P "(\[I\]| \* )" | sed 's/*//g' | sed 's/\[I\]//g' | tr -d ' '; }
searchBin() { searchPath /usr/bin/$1; searchPath /usr/sbin/$1; searchPath /bin/$1; searchPath /sbin/$1; }
install() { emerge $@; }
fi
searchBins() { for executable in "$@"; do searchBin $executable; done | tr "\n" " "; echo; }
searchPaths() { for path in "$@"; do searchPath $path; done | tr "\n" " "; echo; }
installPkgWithPath() { install $(searchPath "$1"); }
installPkgsWithPaths() { install $(searchPaths $@); }
installPkgWithExecutable() { install $(searchBin $1); }
installPkgsWithExecutables() { install $(searchBins $@); }
它创建的函数可以像这样使用:
updatePackageInfo # Equivalent to apt-get update
installPkgWithPath "curl/curl.h" # Installs the package containing the header file curl/curl.h
installPkgsWithPaths "curl/curl.h" "/usr/bin/wget" # Installs multiple packages by file paths
installPkgWithExecutable curl # Install the package that provides the `curl` executable
installPkgsWithExecutables curl wget make # Install all packages required to get these 3 executables
这基本上在 Fedora、RHEL、Debian、Arch、Gentoo、OpenSuse(以及我认为的更多)上运行良好。但它不适用于 Ubuntu,因为 Ubuntu 没有所需的apt-file
软件包(除非您启用Universe
提供它的存储库)。
另一件不起作用的事情是安装类似vlc
Fedora 的东西。在 Fedora 上,您通常会RPM Fusion
为此启用存储库。
我确信其他发行版也有类似的情况。
我考虑的是添加一个--force
标志,设置该标志后,会导致搜索这些存储库并在需要时添加。但我不想最终陷入必须维护存储库列表的情况。我希望大多数发行版以某种方式引用这些半受信任的存储库,这样我就不必为每个发行版维护存储库列表。
有任何想法吗?
答案1
我想有了 Debian 50,000 多个可安装的软件包,我就不需要再去寻找 Debian 镜像之外的东西了。您的想法很酷,但您可能需要更新存储库列表。另外,您将创建弗兰肯发行版,这真的会把事情搞砸!
使用各种力量选项有助于摆脱堵塞,但不建议日常使用。您也许可以添加下标来使用alien
.这个想法非常适合无限制地消耗所有可用的业余时间
我曾经考虑过一个 HTML 系统来保存所有现有的 Linux 文档。我不需要思考太久!
答案2
我以前从未看过这个,但这可能是一个很好的练习......
我是 Arch Linux 用户。我也是 GNOME 用户。我知道有一个 GNOME 应用程序商店[1]它必须与发行版无关,因为 Arch 提供了它,Ubuntu 和 Fedora 也提供了它,等等......
所以,调查gnome-software
[2]其中两个依赖项引起了我的注意:
- 封装套件[3], 被形容为“一个旨在使软件包的安装和更新更容易的系统”
- 应用程序流[4], 被形容为“提供跨发行版创建应用程序商店的标准”
我认为你的问题的答案就在那里,或者至少它们会给你一个很好的起点
[1]https://wiki.gnome.org/Apps/Software/
[2]https://archlinux.org/packages/extra/x86_64/gnome-software/
[3]https://www.freedesktop.org/software/PackageKit/
[4]https://www.freedesktop.org/wiki/Distributions/AppStream/