自动在脚本中添加一个新的索引变量。

huangapple go评论51阅读模式
英文:

Add a new indexed variable on the script automatically

问题

这个脚本会自动在数组中的指定索引处添加新值。

#!/bin/bash
declare -A DATA
DATA[sid0]='aaaa'
DATA[sid1]='bbbb'
DATA[sid2]='cccc'
function newserver {
    sidtotal=0
    indexcount=0
    for indexcount in "${!DATA[@]}"
    do
        if [[ $indexcount == sid* ]]
        then
            sidtotal=$((sidtotal+1))
        fi
    done
    read -p "Name: " id
    DATA["sid$((sidtotal))"]=$id
    echo ${DATA[@]}
    echo sidtotal= $sidtotal
    read -p "Would you like to add more data? [y - n]" MOREDATA
}
newserver

while [ "$MOREDATA" == y ]; do
    newserver
done

这个脚本会自动在数据数组中的指定索引处添加新值...

我想要将值 id 和确定的索引数组 sidtotal 添加到脚本中,但是我也想在添加的同时将这一行添加到脚本中。类似于这样。

.......

DATA[sid0]='aaaa'
DATA[sid1]='bbbb'
DATA[sid2]='cccc'
DATA[sid3]='newdata'

........

这样,当脚本完成时,这个值就不会消失了...

英文:

I have this script who automatically add new values with a determined index o the array.

#!/bin/bash
declare -A DATA
DATA[sid0]='aaaa'
DATA[sid1]='bbbb'
DATA[sid2]='cccc'
function newserver {
    sidtotal=0
    indexcount=0
    for indexcount in "${!DATA[@]}"
    do
        if [[ $indexcount == sid* ]]
        then
            sidtotal=$((sidtotal+1))
        fi
    done
    read -p "Name: " id
    DATA["sid$((sidtotal))"]=$id
    echo ${DATA[@]}
    echo sidtotal= $sidtotal
    read -p "Would like do add more data? [y - n]" MOREDATA
}
newserver

while [ "$MOREDATA" == y ];do
    newserver
done

This script automatically add a new value on the data array on determined index....

I want to add the value id and the determined indexed array sidtotal but, i would like do add in to the script too, at the same moment when i add, the script.sh will add the line. Something like that.

.......

DATA[sid0]='aaaa'
DATA[sid1]='bbbb'
DATA[sid2]='cccc'
DATA[sid3]='newdata'

........

So when the script finish, the value will not disapear...

答案1

得分: 0

将数组定义移到单独的文件中,并在添加新元素时让您的函数覆盖它。

以下将该文件称为data.sh,并假定它的初始内容如下:

declare -A DATA=([sid0]="aaaa" [sid1]="bbbb" [sid2]="cccc")
#!/usr/bin/env bash

# 数据数组在此文件中定义;引入它。
. data.sh

newserver() {
    local sidtotal=0 indexcount=0
    for indexcount in "${!DATA[@]}"
    do
        if [[ $indexcount == sid* ]]; then
            sidtotal=$((sidtotal+1))
        fi
    done
    read -r -p "名称: " id
    DATA["sid$((sidtotal))"]=$id
    echo "${DATA[@]}"
    echo sidtotal= $sidtotal
    # 使用更新后的数组定义覆盖data.sh
    declare -p DATA > data.sh
}

newserver
while true; do
    read -r -p "是否要添加更多数据? [y - n] " MOREDATA
    if [ "$MOREDATA" == y ]; then
        newserver
    else
        break
    fi
done

示例用法:

$ bash demo.sh
名称: dddd
bbbb aaaa dddd cccc
sidtotal= 3
是否要添加更多数据? [y - n] n
$ cat data.sh
declare -A DATA=([sid1]="bbbb" [sid0]="aaaa" [sid3]="dddd" [sid2]="cccc" )

请注意一些其他更改,如修复语法错误,将询问是否继续的提示移到函数之外以及其他一些使 shellcheck 对其提出的投诉较少的杂项更改。

英文:

Move the array definition into a separate file, and make your function overwrite it when adding a new element.

The following calls that file data.sh and assumes it starts out with

declare -A DATA=([sid0]="aaaa" [sid1]="bbbb" [sid2]="cccc")

as its contents.

#!/usr/bin/env bash

# The data array is defined in this file; source it.
. data.sh

newserver() {
    local sidtotal=0 indexcount=0
    for indexcount in "${!DATA[@]}"
    do
        if [[ $indexcount == sid* ]]; then
            sidtotal=$((sidtotal+1))
        fi
    done
    read -r -p "Name: " id
    DATA["sid$((sidtotal))"]=$id
    echo "${DATA[@]}"
    echo sidtotal= $sidtotal
    # Overwrite data.sh with the updated array definition
    declare -p DATA > data.sh
}


newserver
while true; do
    read -r -p "Would you like to add more data? [y - n] " MOREDATA
    if [ "$MOREDATA" == y ]; then
        newserver
    else
        break
    fi
done

Example usage:

$ bash demo.sh
Name: dddd
bbbb aaaa dddd cccc
sidtotal= 3
Would you like to add more data? [y - n] n
$ cat data.sh
declare -A DATA=([sid1]="bbbb" [sid0]="aaaa" [sid3]="dddd" [sid2]="cccc" )

Note a few other changes like fixing syntax errors, moving the prompt asking if you want to continue out of the function, and assorted other things to make shellcheck complain less about it.

答案2

得分: 0

如其他人所指出,你试图做的可能不是一个好主意。然而,从技术上讲,这并不难实现。你的代码的这个最小修改版本演示了一种实现方法:

#!/bin/bash

function newserver {
    sidtotal=0
    indexcount=0
    for indexcount in "${!DATA[@]}"
    do
        if [[ $indexcount == sid* ]]
        then
            sidtotal=$((sidtotal+1))
        fi
    done
    read -p "Name: " id
    DATA["sid$((sidtotal))"]=$id
    echo ${DATA[@]}
    echo sidtotal= $sidtotal
    read -p "Would like do add more data? [y - n]" MOREDATA
}

# Read the program source lines into the 'prog_lines' array and eval the
# definition of the DATA associative array on the last line
readarray -t prog_lines < "${BASH_SOURCE[0]}"
eval "${prog_lines[-1]}"

newserver
while [ "$MOREDATA" == y ];do
    newserver
done

# Update the definition of DATA on the last line and rewrite the program file
prog_lines[-1]=$(declare -p DATA)
printf '%s\n' "${prog_lines[@]}" > "${BASH_SOURCE[0]}"

exit

declare -A DATA=([sid1]="bbbb" [sid0]="aaaa" [sid2]="cccc" )
  • 基本思想是将DATA的定义放在程序文件的最后一行,程序开始时读取它,并在程序结束时更新它。
  • 将修改后的定义放在最后(在程序的最后exit之后)应该避免由于Bash在从源文件读取代码行时执行它们,可能引发的问题。更改正在运行的Bash程序可能会导致其以非常奇怪和潜在危险的方式崩溃,我很早就吃过苦头。
  • 通常情况下,使用eval不是一个好主意。但是,这里的使用不比source data.bash(或. data.bash)更糟糕,因为它等同于eval "$(cat data.bash)"。在所有情况下,只有在保存的DATA定义出现问题时才会出现问题。
  • 该代码至少需要Bash 4.1(2009年发布),因为它使用-1作为索引来访问数组的最后一个元素。
  • 有关printf的使用说明,请参见Is it normal for printf '%s\n' "${array[@]}" to print one line per array element?
英文:

As others have pointed out, what you are trying to do is probably not a good thing to do. However, it is not technically difficult to do. This minimally modified version of your code demonstrates one way to do it:

#!/bin/bash

function newserver {
    sidtotal=0
    indexcount=0
    for indexcount in &quot;${!DATA[@]}&quot;
    do
        if [[ $indexcount == sid* ]]
        then
            sidtotal=$((sidtotal+1))
        fi
    done
    read -p &quot;Name: &quot; id
    DATA[&quot;sid$((sidtotal))&quot;]=$id
    echo ${DATA[@]}
    echo sidtotal= $sidtotal
    read -p &quot;Would like do add more data? [y - n]&quot; MOREDATA
}

# Read the program source lines into the &#39;prog_lines&#39; array and eval the
# definition of the DATA associative array on the last line
readarray -t prog_lines &lt;&quot;${BASH_SOURCE[0]}&quot;
eval &quot;${prog_lines[-1]}&quot;

newserver
while [ &quot;$MOREDATA&quot; == y ];do
    newserver
done

# Update the definition of DATA on the last line and rewrite the program file
prog_lines[-1]=$(declare -p DATA)
printf &#39;%s\n&#39; &quot;${prog_lines[@]}&quot; &gt;&quot;${BASH_SOURCE[0]}&quot;

exit

declare -A DATA=([sid1]=&quot;bbbb&quot; [sid0]=&quot;aaaa&quot; [sid2]=&quot;cccc&quot; )
  • The basic idea is to put the definition of DATA on the last line of the program file, read it at the start of the program, and update it at the end of the program.
  • Putting the modified definition at the end (after the final exit in the program) should avoid potential problems caused by the fact that Bash executes lines of code as it reads them from the source file. Changing a running Bash program can (and does, as I long ago learned the hard way) cause it to break in very strange, and potentially dangerous, ways.
  • Using eval is generally not a good idea. See Why should eval be avoided in Bash, and what should I use instead?. However, its use here is no worse than source data.bash (or . data.bash) because that is equivalent to eval &quot;$(cat data.bash)&quot;. In all cases it's a problem only if the saved definition of DATA is bad.
  • The code requires at least Bash 4.1 (released in 2009) because it uses -1 as an index to access the last element in an array.
  • See Is it normal for printf '%s\n' "${array[@]}" to print one line per array element? for an explanation of the use of printf.

huangapple
  • 本文由 发表于 2023年6月22日 04:41:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76526981.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定