英文:
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 "${!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" )
- 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 thansource data.bash
(or. data.bash
) because that is equivalent toeval "$(cat data.bash)"
. In all cases it's a problem only if the saved definition ofDATA
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论