Ответ 1
Вы действительно хотите сделать
import os
os.environ["MY_DATA"] = "my_export"
Мне нужно сделать такой экспорт в Python:
# export MY_DATA="my_export"
Я пытался:
# -*- python-mode -*-
# -*- coding: utf-8 -*-
import os
os.system('export MY_DATA="my_export"')
Но когда я перечисляю экспорт, "MY_DATA" не появляется:
# export
Как я могу выполнить экспорт с Python без сохранения "my_export" в файл?
Вы действительно хотите сделать
import os
os.environ["MY_DATA"] = "my_export"
export
- это команда, которую вы передаете непосредственно оболочке (например, bash
), чтобы сообщить ей, чтобы добавить или изменить одну из своих переменных окружения. Вы не можете изменить среду оболочки из дочернего процесса (например, Python), это просто невозможно.
Вот что происходит с вами, попробуйте os.system('export MY_DATA="my_export"')
...
/bin/bash process, command `python yourscript.py` forks python subprocess
|_
/usr/bin/python process, command `os.system()` forks /bin/sh subprocess
|_
/bin/sh process, command `export ...` changes local environment
Когда самый нижний подпроцесс /bin/sh
завершает выполнение вашей команды export ...
, он отбрасывается вместе со средой, которую вы только что изменили.
Еще один способ сделать это, если вы спешите и не против взломанного последействия, заключается в том, чтобы выполнить вывод python script в вашей среде bash и распечатать команды для выполнения настройка среды в python. Не идеально, но это может сделать работу в крайнем случае. Он не очень переносится через оболочки, поэтому YMMV.
$(python -c 'print "export MY_DATA=my_export"')
(вы также можете заключить оператор в backticks в некоторых оболочках ``)
Не так просто:
python -c "import os; os.putenv('MY_DATA','1233')"
$ echo $MY_DATA # <- empty
Но:
python -c "import os; os.putenv('MY_DATA','123'); os.system('bash')"
$ echo $MY_DATA #<- 123
Вместо этого вы можете попробовать os.environ [ "MY_DATA" ].
Вид взлома, потому что это не действительно python, делающий что-то особенное здесь, но если вы запустите команду export в той же суб-оболочке, вы, вероятно, получите нужный результат.
import os
cmd = "export MY_DATA='1234'; echo $MY_DATA" # or whatever command
os.system(cmd)
В надежде обеспечить ясность в отношении общей cinfusion...
Я написал много наборов инструментов python ↔ bash ↔ elfbin и правильный способ увидеть, что он выглядит следующим образом:
Каждый процесс (исходник) имеет состояние среды, унаследованное от того, что его вызывало. Любое изменение остается локальным для этого процесса. Перенос состояния среды - это функция сама по себе и работает в двух направлениях, каждая из которых имеет свои собственные предостережения. Наиболее распространенная вещь - изменить среду перед запуском подпроцесса. Чтобы спуститься к металу, посмотрите на exec() - вызов C. Существует вариант, который берет указатель на данные среды. Это единственная фактически поддерживаемая передача среды в типичных ОС.
Сценарии оболочки создадут состояние для передачи при запуске дочерних элементов, когда вы выполняете экспорт. В противном случае он просто использует то, что получил в первую очередь.
Во всех остальных случаях это будет некоторый общий механизм, используемый для передачи набора данных, позволяющих самому вызывающему процессу обновлять его среду на основе результата вывода дочерних процессов.
Пример:
ENVUPDATE = $(CMD_THAT_OUTPUTS_KEYVAL_LISTS)
echo $ENVUPDATE > $TMPFILE
source $TMPFILE
То же самое можно сделать, используя json, xml или другие вещи, если у вас есть инструменты для интерпретации и применения.
Потребность в этом может быть (вероятность 50%) признаком неверного истолкования основных примитивов и что вам нужно улучшить конфигурацию параметров или параметров в вашем решении.....
О, в python я бы сделал что-то вроде... (требуется улучшение в зависимости от вашей ситуации)
import re
RE_KV=re.compile('([a-z][\w]*)\s*=\s*(.*)')
OUTPUT=RunSomething(...) (Assuming 'k1=v1 k2=v2')
for kv in OUTPUT.split(' ')
try:
k,v=RE_KV.match(kv).groups()
os.environ[k]=str(v)
except:
#The not a property case...
pass
eval 'python -c 'import sysconfig;print("python_include_path={0}".format(sysconfig.get_path("include")))''
echo $python_include_path # prints /home/<usr>/anaconda3/include/python3.6m" in my case
python -c 'import sysconfig;print("python_include_path={0}".format(sysconfig.get_path("include")))'
Это запускает скрипт Python, который
eval 'python -c 'import sysconfig;print("python_include_path={0}".format(sysconfig.get_path("include")))''
Он выполняет в текущем экземпляре bash вывод из скрипта python. В моем случае его выполнение:
python_include_path=/home/<usr>/anaconda3/include/python3.6m
Другими словами, он устанавливает переменную среды "python_include_path" с этим путем для этого экземпляра оболочки.
Вдохновлено: http://blog.tintoy.io/2017/06/exporting-environment-variables-from-python-to-bash/
У меня отличный ответ.
#! /bin/bash
output=$(git diff origin/master..origin/develop | \
python -c '
# DO YOUR HACKING
variable1_to_be_exported="Yo Yo"
variable2_to_be_exported="Honey Singh"
… so on
magic=""
magic+="export onShell-var1=\""+str(variable1_to_be_exported)+"\"\n"
magic+="export onShell-var2=\""+str(variable2_to_be_exported)+"\""
print magic
'
)
eval "$output"
echo "$onShell-var1" // Output will be Yo Yo
echo "$onShell-var2" // Output will be Honey Singh
Мистер Алекс Тингл прав насчет этих процессов и субпроцессов
Как это может быть достигнуто, как я уже упоминал выше. Ключевая концепция:
printed
из python, будет сохранено в переменной в переменной bash
в bash
[ output
]eval
print
из python с помощью значимых команд bash
eval
для выполнения в bashИ вы можете увидеть свои результаты
ПРИМЕЧАНИЕ Всегда выполняйте eval
используя double quotes
иначе bash
испортит ваш \n
и результаты будут странными
PS: я не люблю bash, но вы должны его использовать
import os
import shlex
from subprocess import Popen, PIPE
os.environ.update(key=value)
res = Popen(shlex.split("cmd xxx -xxx"), stdin=PIPE, stdout=PIPE, stderr=PIPE,
shell=True).communicate('y\ny\ny\n'.encode('utf8'))
stdout = res[0]
stderr = res[1]
os.system('/home/user1/exportPath.ksh')
exportPath.ksh:
export PATH=MY_DATA="my_export"