Невозможно использовать массив в качестве переменной среды

Попробуйте временно изменить домашний каталог пользователя (например, на /tmp/home/username), изменить uid, а затем изменить homedir на прежний.

Например:

# mkdir -p /tmp/home/jsmith  ## uncomment if required.
usermod -d /tmp/home/jsmith jsmith
usermod -u fixedUID jsmith -o
usermod -d /home/jsmith jsmith

Если домашний каталог пользователя не /home/username, вы можете извлечь настоящий домашний каталог с помощью getent:

# mkdir -p /tmp/home/jsmith  ## uncomment if required.
homedir=$(getent passwd jsmith | awk -F: '{print $6}')
usermod -d /tmp/home/jsmith jsmith
usermod -u fixedUID jsmith -o
usermod -d "$homedir" jsmith
4
19.09.2017, 06:46
2 ответа

Массив bashне может быть переменной среды, так как переменные среды могут быть только парами ключевых строк -значений.

Вы можете сделать то, что делает оболочка со своей переменной $PATH, которая по существу является массивом путей; превратить массив в строку, разделенную определенным символом, иначе не присутствующим в значениях массива:

$ arr=( aa bb cc "some string" )
$ arr=$( printf '%s:' "${arr[@]}" )
$ printf '%s\n' "$arr"
aa:bb:cc:some string:

Или аккуратнее,

arr=( aa bb cc "some string" )
arr=$( IFS=:; printf '%s' "${arr[*]}" )
export arr

Расширением ${arr[*]}будут элементы массива arr, разделенные первым символом IFS, здесь установлено значение :. Обратите внимание, что если сделать это таким образом, элементы строки будут разделены (, а не разделены)на :, что означает, что вы не сможете отличить пустой элемент в конец, если он был.


Очевидно, что альтернативой передаче значений сценарию с использованием переменных окружения является (? )для использования аргументов командной строки:

arr=( aa bb cc )

./some_script "${arr[@]}"

Затем сценарий будет обращаться к переданным аргументам либо один за другим, используя позиционные параметры $1, $2, $3и т. д., либо с помощью$@:

printf 'First I got "%s"\n' "$1"
printf 'Then  I got "%s"\n' "$2"
printf 'Lastly there was "%s"\n' "$3"

for opt in "$@"; do
    printf 'I have "%s"\n' "$opt"
done
22
27.01.2020, 20:45

Текущая ситуация с экспортом массива 10/2021

Экспорт массива реализован не полностью. Вы можете клонировать исходный код с помощью команды git clone https://git.savannah.gnu.org/git/bash.git ~/bash-src. Посмотрите в исходниках bash ~/bash-src/config-top.hзакомментированную строку 154 :

.
/* Define to 1 if you want to be able to export indexed arrays to processes
   using the foo=([0]=one [1]=two) and so on */
/* #define ARRAY_EXPORT 1 */

и, кроме того, раздел кода в ~/bash-src/variables.cв строке 429, в котором говорится

#if defined (ARRAY_VARS)
#  if ARRAY_EXPORT
      /* Array variables may not yet be exported. */
      if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
    {
      string_length = 1;
      temp_string = extract_array_assignment_list (string, &string_length);
      temp_var = assign_array_from_string (name, temp_string, 0);
      FREE (temp_string);
      VSETATTR (temp_var, (att_exported | att_imported));
      array_needs_making = 1;
    }
      else
#  endif /* ARRAY_EXPORT */
#endif

так что, по сути, над этим вопросом нужно еще поработать.

Обходной путь

Тем временем вы можете экспортировать переменную BASH_ENV, которая может указывать на скрипт среды. Я помещаю свой в /etc/bash.environmentи объявляю системные массивы -там. Ваш ~/.bashrcможет содержать что-то вроде export BASH_ENV="~/.bash.environment", теперь каждый процесс bash, выполняемый текущим пользователем, будет источником этого файла.

Как @they упоминается ниже, необходима соответствующая ~/.bashrcконфигурация для работы с интерактивными и неинтерактивными оболочками:

[ -r "~/.bash.environment" ] \
&& source "~/.bash.environment" \
&& export BASH_ENV="~/.bash.environment"

И, наконец, ваше окружение:

# ~/.bash.environment
export HELLO="ee"
export HELLOO=(aaa bbbb ccc)

Непостоянный -Обходной путь

Непостоянное -решение для быстрой и грязной передачи массивов может выглядеть так, что вы назначаете именованный канал, созданный путем замены процесса <(), на BASH_ENVпеременную окружения:

BASH_ENV=<(declare -p HELLO HELLOO) your_script.sh

С наилучшими пожеланиями

0
22.10.2021, 19:15

Теги

Похожие вопросы