usermod
команда позволит Вам изменять основную группу пользователя, дополнительную группу или много других атрибутов. -g
переключитесь управляет основной группой.
Для Ваших других вопросов...
Если Вы указываете группу, groupname
, это не существует во время useradd
этап, Вы получите ошибку - useradd: неизвестная группа groupname
groupadd
команда создает новые группы.
Группа останется, если Вы удалите всех пользователей, содержавших в. Необходимо не обязательно удалить пустую группу.
Создайте hilbert
группа через groupadd hilbert
. Затем переместите использование основной группы David usermod -g hilbert hilbert
. (Обратите внимание на то, что первое hilbert
название группы и второе hilbert
имя пользователя. Это важно в случаях, куда Вы перемещаете пользователя к группе с другим именем),
Можно усложнять вещи немного здесь, все же. Во многих дистрибутивах Linux, простом useradd hilbert
создаст пользователя hilbert
и группа того же имени как основное устройство. Я добавил бы дополнительные группы, указанные вместе с помощью -G
переключатель.
Попытайтесь делать это:
$ arrayA=(1 2 3)
$ x=A
$ var=array$x[@]
$ echo ${!var}
1 2 3
man bash
(расширение параметра):${parameter} The value of parameter is substituted. The braces are required when parameter is a positional parameter with more than one
цифра, или когда параметр сопровождается символом, который не должен быть интерпретирован как часть его имени.
*, Если первый символ параметра является восклицательным знаком (!), уровень переменной абстракции представлен. Bash использует значение переменной, сформированной из остальной части параметра как название переменной; эта переменная затем расширена, и то значение используется в остальной части замены, а не значения самого параметра. Это известно как косвенное расширение. * Исключениями к этому являются расширения $ {! prefix*} и $ {! имя} описанный ниже. Восклицательный знак должен сразу следовать за левой фигурной скобкой для представления косвенности.
никакой путь :(
если Ваши массивы настолько просты, то используйте ассоциативные массивы
declare -A array
array[A]="1 2 3"
array[B]="a b c"
к сожалению, если Ваши массивы более сложны (например, array=( "a b" c )
), это не работало бы. Затем необходимо думать тяжелее о другом способе достигнуть цели.
Таким образом можно создать переменную с динамическим именем (версия bash <4.3).
# Dynamically named array
my_variable_name="dyn_arr_names"
eval $my_variable_name=\(\)
# Adding by index to the array eg. dyn_arr_names[0]="bob"
eval $my_variable_name[0]="bob"
# Adding by pushing onto the array eg. dyn_arr_names+=(robert)
eval $my_variable_name+=\(robert\)
# Print value stored at index indirect
echo ${!my_variable_name[0]}
# Print value stored at index
eval echo \${$my_variable_name[0]}
# Get item count
eval echo \${#$my_variable_name[@]}
Ниже представлена группа функций, которые можно использовать для управления массивами с динамическими именами (версия bash <4.3).
# Dynamically create an array by name
function arr() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
# The following line can be replaced with 'declare -ag $1=\(\)'
# Note: For some reason when using 'declare -ag $1' without the parentheses will make 'declare -p' fail
eval $1=\(\)
}
# Insert incrementing by incrementing index eg. array+=(data)
function arr_insert() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "$1" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
eval $1[\$\(\(\${#${1}[@]}\)\)]=\$2
}
# Update an index by position
function arr_set() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "$1" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
eval ${1}[${2}]=\${3}
}
# Get the array content ${array[@]}
function arr_get() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "$1" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
eval echo \${${1}[@]}
}
# Get the value stored at a specific index eg. ${array[0]}
function arr_at() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "$1" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
[[ ! "$2" =~ ^(0|[-]?[1-9]+[0-9]*)$ ]] && { echo "Array index must be a number" 1>&2 ; return 1 ; }
local v=$1
local i=$2
local max=$(eval echo \${\#${1}[@]})
# Array has items and index is in range
if [[ $max -gt 0 && $i -ge 0 && $i -lt $max ]]
then
eval echo \${$v[$i]}
fi
}
# Get the value stored at a specific index eg. ${array[0]}
function arr_count() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable " 1>&2 ; return 1 ; }
declare -p "$1" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
local v=${1}
eval echo \${\#${1}[@]}
}
array_names=(bob jane dick)
for name in "${array_names[@]}"
do
arr dyn_$name
done
echo "Arrays Created"
declare -a | grep "a dyn_"
# Insert three items per array
for name in "${array_names[@]}"
do
echo "Inserting dyn_$name abc"
arr_insert dyn_$name "abc"
echo "Inserting dyn_$name def"
arr_insert dyn_$name "def"
echo "Inserting dyn_$name ghi"
arr_insert dyn_$name "ghi"
done
for name in "${array_names[@]}"
do
echo "Setting dyn_$name[0]=first"
arr_set dyn_$name 0 "first"
echo "Setting dyn_$name[2]=third"
arr_set dyn_$name 2 "third"
done
declare -a | grep "a dyn_"
for name in "${array_names[@]}"
do
arr_get dyn_$name
done
for name in "${array_names[@]}"
do
echo "Dumping dyn_$name by index"
# Print by index
for (( i=0 ; i < $(arr_count dyn_$name) ; i++ ))
do
echo "dyn_$name[$i]: $(arr_at dyn_$name $i)"
done
done
for name in "${array_names[@]}"
do
echo "Dumping dyn_$name"
for n in $(arr_get dyn_$name)
do
echo $n
done
done
Ниже представлена группа функций, которые можно использовать для управления массивами с динамическими именами (версия bash> = 4.3).
# Dynamically create an array by name
function arr() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -g -a $1=\(\)
}
# Insert incrementing by incrementing index eg. array+=(data)
function arr_insert() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "$1" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
declare -n r=$1
r[${#r[@]}]=$2
}
# Update an index by position
function arr_set() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "$1" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
declare -n r=$1
r[$2]=$3
}
# Get the array content ${array[@]}
function arr_get() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "$1" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
declare -n r=$1
echo ${r[@]}
}
# Get the value stored at a specific index eg. ${array[0]}
function arr_at() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "$1" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
[[ ! "$2" =~ ^(0|[-]?[1-9]+[0-9]*)$ ]] && { echo "Array index must be a number" 1>&2 ; return 1 ; }
declare -n r=$1
local max=${#r[@]}
# Array has items and index is in range
if [[ $max -gt 0 && $i -ge 0 && $i -lt $max ]]
then
echo ${r[$2]}
fi
}
# Get the value stored at a specific index eg. ${array[0]}
function arr_count() {
[[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable " 1>&2 ; return 1 ; }
declare -p "$1" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
declare -n r=$1
echo ${#r[@]}
}
array_names=(bob jane dick)
for name in "${array_names[@]}"
do
arr dyn_$name
done
echo "Arrays Created"
declare -a | grep "a dyn_"
# Insert three items per array
for name in "${array_names[@]}"
do
echo "Inserting dyn_$name abc"
arr_insert dyn_$name "abc"
echo "Inserting dyn_$name def"
arr_insert dyn_$name "def"
echo "Inserting dyn_$name ghi"
arr_insert dyn_$name "ghi"
done
for name in "${array_names[@]}"
do
echo "Setting dyn_$name[0]=first"
arr_set dyn_$name 0 "first"
echo "Setting dyn_$name[2]=third"
arr_set dyn_$name 2 "third"
done
declare -a | grep 'a dyn_'
for name in "${array_names[@]}"
do
arr_get dyn_$name
done
for name in "${array_names[@]}"
do
echo "Dumping dyn_$name by index"
# Print by index
for (( i=0 ; i < $(arr_count dyn_$name) ; i++ ))
do
echo "dyn_$name[$i]: $(arr_at dyn_$name $i)"
done
done
for name in "${array_names[@]}"
do
echo "Dumping dyn_$name"
for n in $(arr_get dyn_$name)
do
echo $n
done
done
Для получения более подробной информации об этих примерах посетите Getting Bashed by Dynamic Arrays, автор Ludvik Jerabek
Esto requirió mucho ensayo y error, pero finalmente funcionó.
Me inspiré un poco en Youness. Pero todas las demás respuestas no ayudaron en mi bash anterior (suse11sp1 [3.2.51 (1 )-release])
El ciclo 'for' se negó a expandir la matriz indirecta, en su lugar, debe expandirlo previamente -, utilícelo para crear otra matriz con su nuevo nombre de variable. Mi ejemplo a continuación muestra un bucle doble, ya que ese es mi uso previsto.
THEBIGLOOP=(New_FOO New_BAR)
FOOthings=(1 2 3)
BARthings=(a b c)
for j in ${THEBIGLOOP[*]}
do
TheNewVariable=$(eval echo \${${j#New_}things[@]})
for i in $TheNewVariable
do
echo $j $i" hello"
echo
done
done
Estoy usando #para eliminar el "Nuevo _" de la primera entrada de matriz, luego lo concateno con "cosas", para obtener "FOOcosas". \${} con echo y eval, luego hacen lo suyo en orden sin arrojar errores, que se envuelve en un nuevo $ ()y se le asigna el nuevo nombre de variable.
$ Test.sh
New_FOO 1 hello
New_FOO 2 hello
New_FOO 3 hello
New_BAR a hello
New_BAR b hello
New_BAR c hello
ACTUALIZACIÓN #####2018/06/07 Recientemente descubrí un giro más en este tema. La variable creada no es en realidad una matriz, sino una cadena delimitada por espacios. Para la tarea anterior, estuvo bien, debido a cómo funciona "for", no lee la matriz, se expande y luego se repite, vea el extracto a continuación:
for VARIABLE in 1 2 3 4 5.. N
do
command1
command2
commandN
done
Pero, luego necesitaba usarlo como una matriz. Para esto necesitaba realizar un paso más. Tomé el código textualmente por Dennis Williamson . Lo he probado y funciona bien.
IFS=', ' read -r -a TheNewVariable <<< ${TheNewVariable[@]}
El "IFS=', '" es una variable que contiene su delimitador. "leer" con "-a" corta y devuelve la picadura a la variable de matriz. Tenga en cuenta que esto no respeta las comillas, pero hay algunas opciones en read para administrar esto, p. Eliminé la bandera -r que no necesitaba. Así que ahora he combinado esta adición en la creación de variables, lo que permite que los datos se traten y direccionen como se debe.
THEBIGLOOP=(New_FOO New_BAR)
FOOthings=(1 2 3)
BARthings=(a b c)
for j in ${THEBIGLOOP[*]}
do
IFS=', ' read -a TheNewVariable <<< $(eval echo \${${j#New_}things[@]})
for i in ${TheNewVariable[@]} #Now have to wrap with {} and expand with @
do
echo $j $i" hello"
echo ${TheNewVariable[$i]} #This would not work in the original code
echo
done
done
Хотя вы можете использовать непрямой доступ, как указано в другом ответе , другим способом (в ksh и Bash 4.3 и новее )будет использование имен. Особенно в случае массивов это может быть более полезным, поскольку вы можете индексировать массив через nameref и не нужно помещать индекс в переменную, используемую в качестве ссылки.
arr1=(a b c)
arr2=(x y z)
typeset -n p=arr1 # or 'declare -n'
echo "${p[1]}" # prints 'b'
Непрямой доступ не работает:
q=arr2
echo "${!q}" # prints 'x', the same as $arr2
echo "${!q[1]}" # doesn't work, it tries to take q[1] as a reference
Как мог бы сказать программист на C, ${!q[1]}
здесь действует так, как если бы q
был массивом указателей, а не указателем на массив.
Мне помогло:
У меня есть массивы, объявленные глобальными из формы:
declare -a total_count
declare -a total_min
declare -a total_max
declare -a total_med
declare -a total_avg
declare -a total_stdev
И я хочу распечатать таблицу, состоящую из содержимого вышеупомянутых массивов, без необходимости выполнять одну и ту же работу снова и снова.
Я хочу, чтобы функция получала префикс имени массива и количество строк, которые я хочу напечатать, и делала все остальное. Основная проблема здесь заключалась в том, чтобы получить доступ к массиву bash по определенному индексу с именем массива, состоящим из функциональной переменной.
Я заметил, что использование eval
дважды может сделать работу. Без этого трюка я увидел ошибку «плохая замена».
function print_table {
name=$1
len=$2
# print banner
echo -n "filename "
for col in _count _min _max _med _avg _stdev
do
echo -n "${name}${col} "
done
echo ""
#print data
for ((i=0;i<len;i++)); do
line="count=\$\{${name}_count[$i]\}"
eval "$line"
line="min=\$\{${name}_min[$i]\}"
eval "$line"
line="max=\$\{${name}_max[$i]\}"
eval "$line"
line="med=\$\{${name}_med[$i]\}"
eval "$line"
line="avg=\$\{${name}_avg[$i]\}"
eval "$line"
line="stdev=\$\{${name}_stdev[$i]\}"
eval "$line"
eval "printf \"%s %d %f %f %f %f %f \n\" \"${filename[$i]}\" \"$count\" \"$min\" \"$max\" \"$med\" \"$avg\" \"$stdev\" "
done
}
!
выполнение передvar
переменная? Как это работает, это, казалось, было заменой истории относительно поиска с помощью Google, но я не мог видеть, как это работало здесь. – Aaron 08.01.2013, 00:44