Понимание переменных окружения в различных контекстах

Это не могло бы работать при каждом обстоятельстве, но попытке

openssl s_client -connect google.com:443 2>&1 | openssl x509 -text | grep DNS
7
07.04.2014, 01:51
3 ответа
[1123219] Основная проблема здесь -- которая объясняет, почему, например, [1123691]$PS1[1123692] не сообщается [1123693]env[1123694] -- заключается в том, что [1123695]env[1123696] представляет собой отчетность из [1123697]неинтерактивной [1123698] среды. Процессы выполняются из развилки интерактивной оболочки [1123699] [1123700], но в том, как установлено их окружение, присутствует тонкость: На самом деле она наследуется через встроенную внешнюю переменную уровня С, установленную для всех процессов [1123701]exec()[1123702] (см. [1123703]man environment[1123704]). Вот иллюстрация:
  • Интересно то, что если вы скомпилируете и запустите его, то содержимое [1123705]**environ[1123706] в точности совпадает с содержимым [1123707]env[1123708]:
  • Единственное отличие - это имя исполняемого файла. Так откуда же взялось [1123709]**environ[1123710] и почему в нем нет, например, [1123711]$PS1[1123712]?
  • Фундаментальное объяснение заключается в том, что процесс всегда создаётся как дети других процессов, и они наследуют [1123713]**environ[1123714], но [1123715]PS1[1123716] никогда не был его частью. При запуске оболочка может исходить из стандартных мест, и эти места отличаются в зависимости от того, является ли оболочка интерактивной или нет; см. [1123717]INVOCATION[1123718] в [1123719]man bash[1123720]. Аспект этого заключается в том, что:
  • PS1 устанавливается [...] [1124246], если bash является интерактивным,[1124247] позволяя оболочке скрипт или стартовый файл для проверки этого состояния.
  • Теперь обратите внимание в [1123723]/etc/bashrc[1123724] на что-то вроде этого:
  • Который является тем местом, где установлено ваше действительное (причудливое) приглашение, и ни он, ни первоначальное значение [1123725]$PS1[1123726] никогда не были [1123727] экспортом [1123728] ed. Начальное значение было создано оболочкой при вызове, так как она была интерактивной, а затем было получено из этого файла -- но [1123729]PS1[1123730] не было помещено в [1123731]**environ[1123732]. Вы можете увидеть это, если выполните:
  • Nothing -- даже если вы [1123733]echo $PS1[1123734] в вашей интерактивной оболочке, это будет определено. Это потому, что [1123735]**environ[1123736] выполняемой [1123737]#!/bin/sh[1123738] оболочки такая же, как и в родительской интерактивной оболочке, но она НЕ содержит [1123739]PS1[1123740]. Это подразумевает, что каждая оболочка использует внутреннюю таблицу глобальных переменных, отдельную, но изначально заполненную, от [1123741]**environ[1123742] (это сбивает с толку, поскольку означает, что [1123743]**environ[1123744] не включает много вещей, называемых

    переменными окружения).

    Содержимое [1123747]**environ[1123748] находится в [1123749]/proc/[PID]/environ[1123750], и если вы проверите, что для вашей текущей интерактивной оболочки, [1123751]cat /proc/$BASHPID/environ[1123752], вы увидите, что [1123753]PS1[1123754] там нет.

    1. Но как вещи попадают в "среду"?
    2. Простой ответ - через системные вызовы. Например, если мы бросим какой-нибудь материал в пример программы на C из более ранних:
    3. MYFOO=whatbar?[1123756] будет в выводе (см. [1123757]man putenv[1123758]). Так как оболочка создает процессы с помощью [1123759]fork()[1123760]ing (который дублирует родительский стек памяти), а затем вызывает [1123761]execv()[1123762] (который передаёт дубликат [1123763]**environ[1123764]), то мы видим механизм, с помощью которого переменные окружения могут быть [1123765]экспортированы[1123766]ed в дочерние процессы. Если вы бросите [1123767]fork()[1123768] в этот пример, вы увидите, что это именно тот случай, и (повторим), этот процесс fork'ing и потенциально exec'ing является тем, как создаются дочерние процессы и наследуются [1123769]**environ[1123770] от их предков. Вызовы [1123771] exec[1123772] заменяют образ процесса, но согласно [1123773] man execv[1123774] и [1123775] man environ[1123776] (nb. некоторые версии первого не ссылаются на это), [1123777]**environ[1123778] передается системой.

      Вот буквальная вилка и выполнение [1123779]/usr/bin/env[1123780] с [1123781]MYFOO=whatbar? [1123782] экспортируется через [1123783]putenv()[1123784]:

      Так где же вещи, которых нет в "окружающей среде"?

      function query_tasks
      {
          if ($args -eq '/?')
          {
              Write-Output "Usage: query_tasks ComputerName taskname"
              Write-Output "Task name defaults to wildcard search and can be multiple words."
              Write-Output "Computer name, and task names must be included."
          }
          elseif ($args.length -lt 2)
          {
              Write-Output "Error: Must include computer name and partial task name to search for."
          }
          else
          {
              $CompName = $args[0]
              $Tasks = $args[1..($args.length-1)]
              $arrTasks = $(schtasks /query /v /fo csv /s $CompName)
              $taskName = "`"*$Tasks*`""
              $arrTask = $arrTasks -like $taskName -split '","'
      
              $arrSchTasksAttributes = @( )
      
              $arrSchTasksAttributes += "HostName"
              $arrSchTasksAttributes += "TaskName"
              $arrSchTasksAttributes += "NextRunTime"
              $arrSchTasksAttributes += "Status"
              $arrSchTasksAttributes += "LastRunTime"
              $arrSchTasksAttributes += "LastResult"
              $arrSchTasksAttributes += "Creator"
              $arrSchTasksAttributes += "Schedule"
              $arrSchTasksAttributes += "TaskToRun"
              $arrSchTasksAttributes += "StartIn"
              $arrSchTasksAttributes += "Comment"
              $arrSchTasksAttributes += "ScheduledTaskState"
              $arrSchTasksAttributes += "ScheduledType"
              $arrSchTasksAttributes += "StartTime"
              $arrSchTasksAttributes += "StartDate"
              $arrSchTasksAttributes += "EndDate"
              $arrSchTasksAttributes += "Days"
              $arrSchTasksAttributes += "Months"
              $arrSchTasksAttributes += "RunAsUser"
              $arrSchTasksAttributes += "DeleteTaskIfNotRescheduled"
              $arrSchTasksAttributes += "StopTaskIfRunsXHoursandXMins"
              $arrSchTasksAttributes += "Repeat_Every"
              $arrSchTasksAttributes += "Repeat_Until_Time"
              $arrSchTasksAttributes += "Repeat_Until_Duration"
              $arrSchTasksAttributes += "Repeat_StopIfStillRunning"
              $arrSchTasksAttributes += "IdleTime"
              $arrSchTasksAttributes += "PowerManagement"
      
      
              $arrTaskObj = $null
              $arrTaskObj = New-Object psobject
              for ($t = 0; $t -lt $arrTask.length; $t++)
              {
                  Add-Member -InputObject $arrTaskObj -MemberType NoteProperty `
                  -Name $arrSchTasksAttributes[$t] -Value $arrTask[$t]
              }
      
              $listHeaders = @{Expression={$_.HostName};Label="Host Name"}, @{Expression={$_.TaskName};Label="Task Name"}, @{Expression={$_.NextRunTime};Label="Next Run Time"}, @{Expression={$_.LastRunTime};Label="Last Run Time"}, @{Expression={$_.LastResult};Label="Last Result"}, @{Expression={$_.Status};Label="Current Status"}
              $arrTaskObj | Format-List $listHeaders
          }
      }
      

      Это приватные данные конкретного экземпляра оболочки. Бэш покажет вам это + унаследованный материал среды через [1123785]set[1123786] без аргументов. Обратите внимание, что этот вывод также включает исходные функции.

      Но, если я найду, например, LC_CTYPE с помощью env | grep "LC_CTYPE", то он не посылает никакого вывода. В общем, локаль показывает мне 13 переменных LC_* и env только девять:

      Я вообще не получаю переменных [1123789]LC_[1123790] из [1123791]env[1123792] (только [1123793]LANG[1123794]), но 13 из [1123795]locale[1123796]. Я бы предположил, что это переменные, заданные вызовом [1123797]locale[1123798] и не экспортированные; тот факт, что вы получаете любую из [1123799]env[1123800], возможно, отражает наивную ошибку где-то в какой-то конфигурации.[1123254].

    15
    27.01.2020, 20:14
    [1123207] Оболочка знает два типа переменных:

    1. "внутренние" переменные, которые известны только оболочке (и подоболочкам)
    2. экспортируемых переменных, "официальные", которые видны [1124316]execve[1124317] и, таким образом, [1124318]env[1124319]. Встроенная оболочка [1124320]export[1124321] показывает экспортируемые переменные.
    3. Если вы выполните
    4. и повторите
    5. , вы увидите это. Переменные можно экспортировать во время создания ([1123675]export foo=bar[1123676]) вместо [1123677]foo=bar[1123678]), их можно экспортировать автоматически при создании или модификации ([1123679]set -a[1123680]), их можно экспортировать позже ([1123681]var=foo; .... ; экспортировать var[1123682]), и их можно "экспортировать" ([1123683] экспортировать -n var[1123684]).
    6. Если оболочка создает "настоящие" подоболочки (по [1123685] a|b[1123686], [1123687](a;b)[1123688], [1123689]$(a)[1123690] и т.д.), она сохраняет несколько неэкспортируемых переменных, чтобы избежать хаоса.[1123218].
    4
    27.01.2020, 20:14
    [1123461] Вывод команды [1124076]locale[1124077] не является списком переменных окружения из текущего окружения. Он является отображением эффективных настроек локали этого процесса (на которые частично влияют определённые переменные окружения) и представлен в том же самом формате [1124078]key=value[1124079], что и команда [1124080]env[1124081].[12140]Здесь вы можете увидеть источник реализации команды eglibc [1124082]locale[1124083]: [1124084]http://www.eglibc.org/cgi-bin/viewvc.cgi/branches/eglibc-2_19/libc/locale/programs/locale.c?view=markup[12141]
    4
    27.01.2020, 20:14

    Теги

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