首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从文件中有条件地大量安装apt软件包?

如何从文件中有条件地大量安装apt软件包?
EN

Ask Ubuntu用户
提问于 2018-07-08 13:54:49
回答 2查看 341关注 0票数 0

目标

我想用一个文件安装多个APT软件包。

代码语言:javascript
复制
apt_install_from_file "packages" # assumes 'packages' is a readable file in the $PWD

注意:我知道还有其他方法可以做到这一点,我正在重新发明轮子来说话,但我希望这样可以让其他人的生活更轻松。

File-Structure

packages

代码语言:javascript
复制
# ppa
ppa "deadsnakes/ppa"

# packages
apt "tree"

# deb
deb "fzy" [args: "https://github.com/jhawthorn/fzy/releases/download/0.9/fzy_0.9-1_amd64.deb", "$HOME", "fzy_0.9-1_amd64.deb"]

需求

  1. 忽略任何以#开头的行,因为这是一个注释
  2. 如果行以ppa开头,那么使用引号括起来的文本运行以下命令。例如ppa "deadsnakes/ppa" => sudo add-apt-repository -y ppa:deadsnakes/ppa &> /dev/null
  3. 如果行以apt开头,那么使用引号括起来的文本运行以下命令。例如apt "tree" => sudo apt install --allow-unauthenticated -qqy tree
  4. 如果行以deb开头,那么获取由引号括起来的文本,以及以引号括起来的args后面的文本。

电流函数:

代码语言:javascript
复制
apt_install_from_file() {

    declare -r FILE_PATH="$1"

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # Install package(s)

    if [ -e "$FILE_PATH" ]; then

        cat < "$FILE_PATH" | while read -r LINE; do
            if [[ "$LINE" == *"#"* || -z "$LINE" ]]; then
                continue
            elif [[ "$LINE" == *"ppa"* || -z "$LINE" ]]; then
                # ppa= Grab text enclosed by quotes following "ppa"
                sudo add-apt-repository -y ppa:"$ppa" &> /dev/null \
                   && sudo apt update
            elif [[ "$LINE" == *"apt"* || -z "$LINE" ]]; then
                package="$LINE" # Grab text enclosed by quotes following "apt"
                sudo apt install --allow-unauthenticated -qqy "$package"
            elif [[ "$LINE" == *"deb"* || -z "$LINE" ]]; then
                #package_name= Grab text enclosed by quotes following "deb"
                #url= Grab text enclosed by quotes following "args"
                #target_path= Grab text enclosed by quotes following "args"
                #file_name= Grab text enclosed by quotes following "args"
                #file_path="$target_path" + "/" + "$file_name"  

                wget $url -O $file_path && \
                   sudo dpkg -i $file_path && sudo apt-get install -f && \
                   sudo rm -rf $file_path && sudo apt autoremove -qqy
            fi
        done

    fi

}

问题

我需要帮助填写空白的功能,给我的需求清单。

EN

回答 2

Ask Ubuntu用户

回答已采纳

发布于 2018-07-08 16:09:42

这里使用的语法并没有给shell脚本带来任何好处,但是如果使用正则表达式,解析该文件就会稍微容易一些。Bash的正则表达式比较将组(...)保存在BASH_REMATCH数组中,因此您可以一次性测试有效行并对其进行解析。例如:

代码语言:javascript
复制
#! /bin/bash
declare -A regex
regex["comment"]='^#(.*)'
regex["ppa"]='ppa "(.*)"'
regex["apt"]='apt "(.*)"'
regex["deb"]='deb "(.*)" \[args: "(.*)", "(.*)", "(.*)"\]'
while read LINE
do
    if [[ $LINE =~ ${regex[comment]} ]]
    then
        printf "Comment: %s\n" "${BASH_REMATCH[1]}"
        continue
    elif [[ $LINE =~ ${regex[ppa]} ]]
    then
        ppa=${BASH_REMATCH[1]}
        printf "PPA: %s\n" "$ppa"
    elif [[ $LINE =~ ${regex[apt]} ]]
    then
        package=${BASH_REMATCH[1]}
        printf "APT: %s\n" "$package"
    elif [[ $LINE =~ ${regex[deb]} ]]
    then
        package_name=${BASH_REMATCH[1]}
        url=${BASH_REMATCH[2]}
        target_path=${BASH_REMATCH[3]}
        file_name=${BASH_REMATCH[4]}
        file_path="$target_path/$file_name"

        printf "package_name: %s\n" "$package_name"
        printf "url: %s\n" "$url"
        printf "file_path: %s\n" "$file_path"
    fi
done < "$1"

使用示例文件:

代码语言:javascript
复制
$ ./foo.sh foo.txt
Comment:  ppa
PPA: deadsnakes/ppa
Comment:  packages
APT: tree
Comment:  deb
package_name: fzy
url: https://github.com/jhawthorn/fzy/releases/download/0.9/fzy_0.9-1_amd64.deb
file_path: $HOME/fzy_0.9-1_amd64.deb
票数 1
EN

Ask Ubuntu用户

发布于 2018-07-08 15:06:22

背景:

经过一番研究和尝试,我发现我可以将工具cutecho结合使用。

示例:

要实现所需的输出,请举下面的例子。

packages

代码语言:javascript
复制
# packages
apt "tree"

test.sh

代码语言:javascript
复制
apt_install_from_file() {

    declare -r FILE_PATH="$1"

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # Install package(s)

    if [ -e "$FILE_PATH" ]; then

        cat < "$FILE_PATH" | while read -r LINE; do

            if [[ "$LINE" == *"#"* || -z "$LINE" ]]; then
                continue
            elif [[ "$LINE" == *"apt"* || -z "$LINE" ]]; then
                package="$(echo $LINE | cut -d \" -f2)"
                echo "$package"
            fi

        done
    fi

}

使用

./test.sh packages

分解:

给定行package="$(echo $LINE | cut -d \" -f2)",让我们对其进行分解。

  1. 首先,我们echo行的内容。
  2. 然后,我们将结果转化为cut,它根据给定的分隔符将$LINE的内容拆分为多个字段。在我们的例子中,分隔符是"。我们必须在\前面放置一个",因为引号字符必须转义。
  3. 接下来,我们获取这个拆分的第二个字段,其中包含tree
  4. 最后,我们将$()返回的内容存储到package中,其中的情况是tree (例如$() => tree)。

修正函数:

代码语言:javascript
复制
apt_install_from_file() {

    declare -r FILE_PATH="$1"

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # Install package(s)

    if [ -e "$FILE_PATH" ]; then

        cat < "$FILE_PATH" | while read -r LINE; do
            if [[ "$LINE" == *"#"* || -z "$LINE" ]]; then
                continue
            elif [[ "$LINE" == *"ppa"* || -z "$LINE" ]]; then
                ppa="$(echo $LINE | cut -d \" -f2)"
                sudo add-apt-repository -y ppa:"$ppa" &> /dev/null \
                   && sudo apt update
            elif [[ "$LINE" == *"apt"* || -z "$LINE" ]]; then
                package="$(echo $LINE | cut -d \" -f2)"
                sudo apt install --allow-unauthenticated -qqy "$package"
            elif [[ "$LINE" == *"deb"* || -z "$LINE" ]]; then
                package_name="$(echo $LINE | cut -d \" -f2)"
                url="$(echo $LINE | cut -d \" -f4)"
                target_path="$(echo $LINE | cut -d \" -f6)"
                file_name="$(echo $LINE | cut -d \" -f8)"
                file_path="$target_path/$file_name"  

                wget $url -O $file_path && \
                   sudo dpkg -i $file_path && sudo apt-get install -f && \
                   sudo rm -rf $file_path && sudo apt autoremove -qqy
            fi
        done

    fi

}

结论:

这可能不是我上面列出的问题的最好解决方案,而且它确实是一个讨厌的解决方案,所以如果有一个更好的解决方案,请不要犹豫地写一个更新的答案!

票数 1
EN
页面原文内容由Ask Ubuntu提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://askubuntu.com/questions/1053252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档