Отображение даты в Solaris 11

Использование соответствия префикса имени переменной и косвенного обращения к переменной вbash:

proj_env_repo_db_username=username
proj_env_repo_db_host=host
proj_env_repo_db_port=port

for variable in "${!proj_env_repo@}"; do
    export "TF_ENV${variable#proj_env_repo}"="${!variable}"
done

Цикл использует "${!proj_env_repo@}"для создания списка имен переменных, которые имеют префикс имени proj_env_repo. В каждой итерации $variableбудет именем одной из этих переменных.

Внутри цикла exportиспользуется для создания новой переменной среды путем удаления префикса proj_env_repoи замены его строкой TF_ENV. Значение для новой переменной окружения получается с помощью косвенной переменной ${!variable}, т. е. значения переменной, имя которой хранится в $variable.

Чтобы дополнительно сбросить исходную переменную, используйте unset "$variable"после exportдо конца цикла.

Тестовый запуск с включенной трассировкой:

$ bash -x script.sh
+ proj_env_repo_db_username=username
+ proj_env_repo_db_host=host
+ proj_env_repo_db_port=port
+ for variable in "${!proj_env_repo@}"
+ export TF_ENV_db_host=host
+ TF_ENV_db_host=host
+ for variable in "${!proj_env_repo@}"
+ export TF_ENV_db_port=port
+ TF_ENV_db_port=port
+ for variable in "${!proj_env_repo@}"
+ export TF_ENV_db_username=username
+ TF_ENV_db_username=username

Как функция, принимающая префикс старого имени в качестве первого аргумента и новый префикс в качестве второго аргумента:

rename_var () {
    # Make sure arguments are valid as variable name prefixes
    if ! [[ $1 =~ ^[a-zA-Z_][a-zA-Z_0-9]*$ ]] ||
       ! [[ $2 =~ ^[a-zA-Z_][a-zA-Z_0-9]*$ ]]
    then
        echo 'bad variable name prefix' >&2
        return 1
    fi

    eval 'for variable in "${!'"$1"'@}"; do
              export "'"$2"'${variable#'"$1"'}"="${!variable}"
          done'
}

Здесь мы прибегаем к использованию evalповерх цикла, поскольку bashне поддерживает синтаксис ${!$1@}. Функция создает соответствующий шелл-код (в виде строки )для переименования переменных в соответствии со значениями $1и$2(1-го и 2-го аргументов, переданных функции ), а затем использует evalдля выполнения этого шелл-кода.

Эту функцию можно использовать как

rename_var project_env_repo TF_ENV

... или, используя переменные,

rename_var "$old_variable_prefix" "$new_variable_prefix"

Примечание :При выполнении подобных действий (с использованием evalпользовательского ввода )вы должны проверить, что код, который вы оцениваете, действителен и соответствует вашим ожиданиям. это быть. В данном случае это означает проверку $1и $2как допустимых префиксов имен переменных.В противном случае хотя бы кавычки и }вызовут синтаксические ошибки в eval, и есть вероятность внедрения команд.


Примечание :Впервые (я думаю ), что у меня когда-либо было использованиеeval. Я бы никогда не поставил себя в положение, когда мне нужно использовать приведенный выше код, но я, очевидно, не знаю предыстории вопроса, так что это не настоящая критика вопроса (, который сам по себе интересен. ).

Похожие (на сайте Software Engineering):

2
20.11.2020, 07:36
1 ответ

Возможно, потому что вы запустили его в 12 :50, где date +%Mдает вам 50, что становится 45, если вычесть 5, и -5, если вычесть 55.

В 12 :00 вы бы тоже получили -5 с первым.

В 12 :07 вы получили бы 12:2вместо 12:02, а в 12 :09 некоторые оболочки жаловались, что 09не является допустимым восьмеричным числом. Вы не можете просто вычесть 5 из поля минут, чтобы получить время на 5 минут раньше.Учтите, что, например, в Jan 1 00:00это должно дать вам Dec 31 23:55.

Для расчета даты в Solaris можно использовать perlили zsh, хотя последний не всегда установлен по умолчанию. Чтобы получить время, которое было 5 минут назад:

perl -MPOSIX -le 'print strftime("%b %d %R", localtime(time - 5*60))'

или:

zsh -c 'zmodload zsh/datetime; strftime "%b %d %R" $((EPOCHSECONDS - 5*60))'

На самом деле, начиная с версии 11 Solaris, /bin/shи /bin/kshна самом деле являются ksh93, поэтому вы также можете использовать kshтам (лучше не sh, поскольку shэто в настоящее время реализован ksh93, это может измениться в будущем, а стандартный shязык не имеет этих функций):

ksh -c 'printf "%(%b %d %R)T\n" "5 minutes ago"'

Как указано в комментариях @glennjackman, если у вас установлено bash, вы также можете выполнить:

bash -c 'printf -v t "%(%s)T" -1 && printf "%(%b %d %R)T\n" "$((t - 5*60))"'

(поддержка %sи достаточно свежая версия bash были добавлены в выпуск 11 Solaris ).

И пока мы собираемся добавить больше языков, если у вас есть интерпретатор TCL, такой какexpect:

expect -c 'puts [clock format [
  clock add [clock seconds] -5 minute] -format "%b %d %R"]'

Илиpython3:

python3 -c 'import time; print(time.strftime("%b %d %R", time.localtime(time.time() - 5*60)))'
6
28.04.2021, 23:03

Теги

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