env
и printenv
выводят список строк среды (, предназначенных для содержания определений переменных среды ), которые даются им командой, которая их выполняет. В конце концов вызывающий абонент выполнит:
execve("/usr/bin/env", argv, envp);
системный вызов, где argv
и envp
— два списка строк.
env
/ printenv
просто напечатайте список строк в envp
, по одной на строку.
По соглашению, строки в envp
имеют формат var=value
, но они не обязательно должны быть (Я не знаю ни одной execve()
реализации, обеспечивающей его )и большинство Реализациям env
, printenv
все равно, когда они их отображают.
Когда вызывающий объект является оболочкой POSIX, он будет включать в envp
, который он передает в env
, список своих переменных оболочки, помеченных для экспорта (, либо потому, что пользователь вызвал export
/ typeset -x
на нем, или потому что переменная уже была в среде, которую оболочка получила при запуске -up ).
Если некоторые переменные среды, полученные оболочкой при запуске -, не могли быть сопоставлены с переменной оболочки или если какая-либо из полученных строк envp
не содержала символ =
, в зависимости от в реализации оболочки эти строки будут передаваться нетронутыми, или оболочка удалит их или некоторые из них.
Пример с bash
, использование GNU env
для передачи списка произвольных имен переменных(env
не может передавать произвольные строки envp, они должны содержать =
, а те, которые используют setenv()
не может пройти те, которые начинаются с =
¹ ).
$ env -i '=foo' '1=x' '+=y' bash -c printenv
+=y
1=x
[...]
(переменная с пустым именем была удалена, но не другие ).
Кроме того, если оболочка получила несколько строк envp
для одного и того же имени переменной, в зависимости от оболочки,они все будут переданы, или только первый, или только последний.
set
в оболочках POSIX выводит список переменных оболочки, включая не -скалярные для оболочек, которые поддерживают типы массивов/хэшей, независимо от того, помечены они для экспорта или нет.
В оболочках POSIX вы также можете использовать export -p
для вывода списка переменных, помеченных для экспорта. В отличие от env
/ printenv
, здесь также перечислены переменные, помеченные для экспорта, но еще не получившие никакого значения.
В Korn -, подобно оболочкам, таким как ksh
, zsh
или bash
, вы также можете использовать typeset
для получения дополнительной информации, включая атрибуты переменных, и списка переменных по типу (, например typeset -a
. ] для вывода списка переменных массива ).
Здесь, добавляя USER_ENVI=10
к вашему ~/.bashrc
, вы настраиваете интерактивные вызовы оболочки bash
без входа в систему -для определения переменнойUSER_ENVI
оболочки при запуске -вверх. Поскольку вы не использовали export
, эта переменная остается переменной оболочки (, если только она не находилась в среде, когда bash
запускалась ), поэтому она не передается в качестве переменных среды выполняемым командам. этой оболочкой.
/etc/environment
в Ubuntu 16.04 считывается подключаемым модулем аутентификации pam_env.so
. Приложения, которые входят в систему, такие как login
, sshd
, lightdm
, будут читать эти файлы, если они настроены на использование pam_env.so
в /etc/pam.d
, и передавать соответствующие переменные среды (ничего не делать с переменными оболочки здесь )к команде, которую они начинают от вашего имени после аутентификации (, например, в вашей оболочке входа в систему для login
/ sshd
или в вашем графическом менеджере сеансов для lightdm
... ).
Поскольку среда наследуется по умолчанию, когда ваш диспетчер сеансов запускает эмулятор терминала, который, в свою очередь, выполняет вашу оболочку входа в систему, эти переменные среды будут передаваться на каждом этапе,и ваша оболочка сопоставит их с переменными оболочки, которые вы можете расширить в командной строке с помощью таких вещей, как echo "$VAR"
.
pam_env
файлы env, такие как /etc/environment
, выглядят как сценарии оболочки, но pam_env
не вызывает оболочку для их анализа и понимает только подмножество синтаксиса оболочки и позволяет определять только переменные, имена которых состоят из одного или нескольких символов ASCII. alpha -числовые символы или символы подчеркивания (позволяет определить переменную 123
, хотя это не является допустимым именем переменной оболочки POSIX ).
¹, чтобы передать список произвольных строк env, вы также можете вызвать execve()
напрямую, как с:
perl -e 'require "syscall.ph";
$cmd = "/bin/zsh";
$args = pack("p*x[p]", "sh", "-c", "printenv");
$env = pack("p*x[p]", "a=b", "a=c", "", "+=+", "=foo", "bar");
syscall(SYS_execve(), $cmd, $args, $env)'
здесь тестирование с zsh
вместоbash
Уже написано несколько команд для запуска команды на нескольких машинах. Потратив небольшое количество времени на настройку, вы получите дивиденды. Некоторые из наиболее известных из них: ansible , chef , terraform и puppet .
С их помощью вы можете развернуть простой скрипт, чтобы сказать /root/pwupdate, содержащий
#!/bin/sh
sed -i 's/old_encrypted_password/new_encrypted_password/' "$@"
пометить его как исполняемый, а затем приказать ansible и другим запустить
EDITOR=/root/pwupdate vipw
Другим, более интерактивным подходом может быть использование командной строки tmux для открытия терминалов для каждой из машин (, обычно использующих ssh ), а затем указание запустить ту же команду на все терминалы одновременно. Я думаю, что этот подход хорош для 5 машин, но использовать его для 10 и, вероятно, громоздко для 36. Однако у него есть то преимущество, что вам не нужно ничего настраивать по сравнению с тем, что, как я ожидаю, у вас уже есть.