Например, могу ли я просто использовать значения
cutime
иcstime
процесса init пространства имен для получения общего использования процессора?
Это будет включать только время waited-for (и, следовательно, завершенных) дочерних и потомков (или рип-процессов в случае init
). Таким образом, вы получите время только для умерших сирот.
Если вы вычислите сумму cutime и cstime всех процессов в пространстве имен (остерегайтесь условий гонки), вы получите суммарное время всех текущих и прошлых процессов в этом пространстве имен, кроме тех, которые присоединились к пространству имен (например, с помощью nsenter -p
), чье время будет учитываться их родителем в исходном пространстве имен (я обнаружил, что эти процессы имеют PPID 0 в присоединенном пространстве имен).
Также, если я смонтирую файловую систему
/proc
пространства имен (а не корневого пространства имен), будет ли/proc/stat
показывать загрузку процессора только этого конкретного пространства имен?
Это легко проверить:
$ grep cpu /proc/stat
cpu 69003764 88576 8499514 244070762 5120799 0 407453 0 0 0
cpu0 34269946 49008 4228860 122466614 2365498 0 55409 0 0 0
cpu1 34733818 39567 4270653 121604147 2755300 0 352044 0 0 0
$ sudo unshare --mount-proc -mpf grep cpu /proc/stat
cpu 69005266 88576 8499588 244072663 5120837 0 407462 0 0 0
cpu0 34270449 49008 4228896 122467803 2365522 0 55410 0 0 0
cpu1 34734816 39567 4270692 121604860 2755315 0 352051 0 0 0
Так что, похоже, нет.
AFAICT, вы должны быть в состоянии вычислить статистику из корневого пространства имен.
Например, для пространства имен pid $pid
, с zsh
и perl
:
perl -l -0777 -ne '
if (/\(.*\)(?: .*?){12} (.*?) (.*?) (.*?) (.*?)/) {$s+=$1+$2+$3+$4}
END{print $s}' /proc/*/ns/pid(e:'[[ $REPLY -ef /proc/$pid/ns/pid ]]'::h:s/ns/stat)
То есть, сложите поля с 14 по 17 из /proc/pid/stat всех процессов, которые имеют такое же пространство имен pid, как $pid
.
Как сказано выше, это не включает время процессов, которые nsenter
ed пространство имен позже и умерли (ни детей, которых они ждали (другие, похоже, были разорваны init пространства имен)).
Обратите внимание, что имена переменных в верхнем регистре, как правило, небезопасны. $ENV
, например, является особенным во многих оболочках. В этих оболочках его значение должно быть путем к файлу, который будет получен перед запуском определенных типов оболочек. Оболочка bash
использует $ENV
в режиме POSIX.
Так, вbash
:
declare -A account
account["develop"]=12345678
account["staging"]=9128312
account["production"]=123123
mode=$run_mode
aws events put-targets \
--rule {{ stack_name | lower }}-hello-world \
--targets "Id"="1","Arn"="arn:aws:lambda:us-west-2:${account[$mode]}:function:hello-wolrd"
Это устанавливает ассоциативный массив, account
, который содержит данные для режимов разработки, подготовки и производства. Затем он определяет используемый нами режим и выполняет команду с правильными данными из массива account
. Предполагается, что переменная run_mode
является переменной окружения, содержащей одну из строк develop
, staging
или production
.
Ассоциативные массивы были введены в bash
4.0.
Я использовал вашу команду aws
так, как вы ее написали (, за исключением добавления новых строк и моей account
переменной ), хотя {{ stack_name | lower }}-hello-world
, вероятно, не соответствует вашим ожиданиям (он попытается выполнить lower
как команду ). Поскольку я не знаю aws
, я не знаю, как это должно выглядеть, но, вероятно, это следует процитировать.
Устранение проблем пользователя mosvy в комментариях:В случае, когда переменные DEV_ACCOUNT
и т. д. являются переменными среды, и правильный выбор должен быть сделан на основе того, что представляет собой переменная ENV
:
declare -A account
account["DEV"]=$DEV_ACCOUNT
account["STAGE"]=$STAGE_ACCOUNT
account["PRD"]=$PRD_ACCOUNT
mode=$ENV
# the rest as before
Я повторю то, что Кусалананда сказал о неиспользовании ALLCAPS для имен переменных в сценариях оболочки. Как правило, это плохая идея и может вызвать проблемы, когда ваши имена переменных сталкиваются с переменными среды по умолчанию. И я также согласен с тем, что лучший способ сделать это — использовать ассоциативный массив, как он описывает в своем ответе.
В любом случае, если вы настаиваете на (неправильном )способе вместо массива, вам нужно будет сделать что-то вроде этого:
varname="$env"_account
aws events put-targets --rule {{ stack_name | lower }}-hello-world \
--targets "Id"="1","Arn"="arn:aws:lambda:us-west-2:${!varname}:function:hello-world"
Синтаксис ${!var}
будет расширяться до значения переменной с именем var
. Например:
$ foo="foovar"
$ bar=foo
$ echo ${!bar}
foovar
А если серьезно, просто не делай этого. Это сложно, громоздко, трудно читать, сложнее поддерживать, и ассоциативный массив просто решит все эти проблемы за вас.
Спасибо всем, кто опубликовал ответы на мой вопрос. Я внедрил массивы bash для решения своей проблемы. Но мой друг предложил простое решение
printenv `echo $ENV`_ACCOUNT
решил мою проблему.