首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash:如何向存储在变量中的数组添加元素?

Bash:如何向存储在变量中的数组添加元素?
EN

Stack Overflow用户
提问于 2021-01-14 18:47:45
回答 3查看 121关注 0票数 1

TL;博士

在bash中有两个数组变量,archPkgsnpmPkgs。在后面的代码中,我有一个变量pkgPlatform,它可以指向这两个变量中的任何一个。我想通过这个变量向数组中添加一个元素。我怎么才能在巴什做到这一点?

详细信息

我正试图用Python和Bash编写一个安装后脚本,我正在编写一个bast脚本来安装所有所需的包。下面是它的代码。

代码语言:javascript
复制
# List of all Arch packages
archPkgs=(
        # Display server
        'xorg'

        # Display manager
        'lightdm'
        'lightdm-webkit2-greeter'
        'lightdm-webkit-theme-litarvan'

        # Editor
        'neovim-nightly-bin'

        # WM
        'i3-gaps'
        'i3lock'
        'i3status'
        'picom'
        'rofi'

        # Syncing
        'syncthing'

        # Printing
        'cups'

        # Networking
        'network-manager-applet'
        'avahi'
        'nss-mdns'
        'reflector'

        # Browsing
        'firefox'
        'firefox-nightly'

        # Terminals, shell, programming, and other programsn and utilities
        'kitty'
        'bash-completion'
        'nodejs'
        'npm'
        'python'
        'python-pip'

        # Notifications
        'dunst'

        # Gaming
        'steam'

        # Media
        'vlc'
        'playerctl'
        'spotify'

        # Audio
        'pasystray'
        'pulseaudio'
        'pulseaudio-alsa'
        'pulseaudio-bluetooth'
        'pavucontrol'
        'lib32-libpulse'
        'lib32-alsa-plugins'
        'alsa-utils'
        'alsa-firmware'

        # Fonts
        'noto-fonts-cjk'
        'noto-fonts-emoji'
        'ttf-iosevka'
        'ttf-liberation'
        'ttf-opensans'

        # Drive tools + backups
        'udiskie'
        'borg'

        # Power management
        'xfce4-power-manager'

        # Themes
        'arc-gtk-theme'
        'breeze'

        # Screenshots
        'flameshot'

        # Bluetooth
        'blueman'
        'bluez'
        'bluez-utils'
)

npmPkgs=(
    # Language servers
    'vim-language-server'
    'bash-language-server'

    # Type checkers
    'pyright'
)


while true; do
    echo Are there any packages you would like to manage? Enter [arch/npm] [add/remove][ name of package].
    read pkgPlatform pkgAction pkgName

    if [ "$pkgPlatform" == 'arch' ]; then
        pkgPlatform=archPkgs
    elif [ "$pkgPlatform" == 'npm' ]; then
        pkgPlatform=npmPkgs

    elif [ "$pkgPlatform" == 'quit' ] || [ "$pkgAction" == 'quit' ] || [ "$pkgAction" == 'quit' ]; then
        echo Continuing...
        break

    else
        echo "Unknown option."
        continue
    fi

    if [ "$pkgPlatform" != 'quit' ] && [ "$pkgAction" != 'quit' ] && [ "$pkgName" != 'quit' ]; then
        while true; do
            if [ "$pkgAction" == 'add' ]; then
                $pkgPlatform+=pkgName
                break

            elif [ "$pkgAction" == 'remove' ]; then
                unset "$pkgName"[$pkgPlatform]
                break

每当我运行它,就会发生这样的事情。

代码语言:javascript
复制
[johnny@lj-laptop post_install_scripts]$ ./02_pkgs.sh 
Packages to be installed:

Arch Packages
xorg lightdm lightdm-webkit2-greeter lightdm-webkit-theme-litarvan neovim-nightly-bin i3-gaps i3lock i3status picom rofi syncthing cups network-manager-applet avahi nss-mdns reflector firefox firefox-nightly kitty bash-completion nodejs npm python python-pip dunst steam vlc playerctl spotify pasystray pulseaudio pulseaudio-alsa pulseaudio-bluetooth pavucontrol lib32-libpulse lib32-alsa-plugins alsa-utils alsa-firmware noto-fonts-cjk noto-fonts-emoji ttf-iosevka ttf-liberation ttf-opensans udiskie borg xfce4-power-manager arc-gtk-theme breeze flameshot blueman bluez bluez-utils

npm Packages
vim-language-server bash-language-server pyright
Are there any packages you would like to manage? Enter [arch/npm] [add/remove] [name of package].
When you are satisfied, enter "quit" instead of "add" or "remove".
npm add test
./02_pkgs.sh: line 153: npmPkgs+=pkgName: command not found
Packages to be installed:

Arch Packages
xorg lightdm lightdm-webkit2-greeter lightdm-webkit-theme-litarvan neovim-nightly-bin i3-gaps i3lock i3status picom rofi syncthing cups network-manager-applet avahi nss-mdns reflector firefox firefox-nightly kitty bash-completion nodejs npm python python-pip dunst steam vlc playerctl spotify pasystray pulseaudio pulseaudio-alsa pulseaudio-bluetooth pavucontrol lib32-libpulse lib32-alsa-plugins alsa-utils alsa-firmware noto-fonts-cjk noto-fonts-emoji ttf-iosevka ttf-liberation ttf-opensans udiskie borg xfce4-power-manager arc-gtk-theme breeze flameshot blueman bluez bluez-utils

npm Packages
vim-language-server bash-language-server pyright
Are there any packages you would like to manage? Enter [arch/npm] [add/remove] [name of package].
When you are satisfied, enter "quit" instead of "add" or "remove".

问题似乎在第153行。

我现在不太确定我的选择是什么。我粘贴了所有系统更改行注释的脚本,但是在运行它之前,您仍然应该看看它。

很明显,这个脚本还没有完成,我计划早些时候重新安排很多东西。

EN

回答 3

Stack Overflow用户

发布于 2021-01-14 19:20:30

变化

代码语言:javascript
复制
    if [ "$pkgPlatform" == 'arch' ]; then
        pkgPlatform=archPkgs
    elif [ "$pkgPlatform" == 'npm' ]; then
        pkgPlatform=npmPkgs

代码语言:javascript
复制
    if [ "$pkgPlatform" == 'arch' ] || [ "$pkgPlatform" == 'npm' ]; then
        declare -n platformPkgs="${pkgPlatform}Pkgs"

这使platformPkgs成为指向所需数组的nameref。然后,您可以像普通数组变量一样使用platformPkgs

然后改变

代码语言:javascript
复制
            if [ "$pkgAction" == 'add' ]; then
                $pkgPlatform+=pkgName
                break

            elif [ "$pkgAction" == 'remove' ]; then
                unset "$pkgName"[$pkgPlatform]
                break

代码语言:javascript
复制
            if [ "$pkgAction" == 'add' ]; then
                platformPkgs+=( "$pkgName" )
                break

            elif [ "$pkgAction" == 'remove' ]; then
                ## not this => unset "platformPkgs[$pkgName]"
                # first, iterate through the array to find
                # the index for this value $pkgName,
                # then, unset "platformPkgs[$index]"
                # or rewrite the array except for the element at that index: 
                #   platformPkgs=( "${platformPkgs[@]:0:index}" "${platformPkgs[@]:index+1}" )
                break
票数 4
EN

Stack Overflow用户

发布于 2021-01-14 19:18:10

您想要执行的第153行是

代码语言:javascript
复制
npmPkgs+=($pkgName)

但是在变量本身中有你的目标变量。请记住,shell的第一个爱好是构造命令行,变量替换只在您用$运算符指向它的地方完成。

用暴力的方法来做这件事

代码语言:javascript
复制
eval $pkgPlatform'+=($pkgname)'

这样做的目标名称替换,然后撤销结果行。

作为一个不相关的注释,您可以使用一些case语句来清理这个脚本。

票数 2
EN

Stack Overflow用户

发布于 2021-01-14 19:17:59

您所面临的错误是因为您没有正确地将项附加到数组中,

代码语言:javascript
复制
$pkgPlatform+=pkgName ##that way the bash script can't get what you mean

因此,当您将一个项添加到变量pkgPlatform中时,可以这样做:

代码语言:javascript
复制
pkgPlatform+=("$pkgName")
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65725139

复制
相关文章

相似问题

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