I am having the following problem with python, being used to generate
files on Linux, that are being read on Windows. Python is auto-escaping
the strings, so that when written to a file, they are incorrect.
In my shell I have the environment variable set to a UNC path:
camd011> setenv python_error "\\\\a\\b\\c"
camd011> echo $python_error
\\a\b\c
I then retrieve this in python, as it will be used to generate C code
and a #include directive. However when I retrieve the value in python:
camd011> python
Python 1.6.1 (#1, Oct 17 2013, 15:08:20) [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.
Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved.
>>> import os
>>> value = os.environ['python_error']
>>> value
'\\\\\\\\a\\\\b\\\\c'
As you can see above it has been auto-escaped, thus when I write it to a file:
>>> f = open("temp.txt", "w")
>>> f.write(value)
>>> f.close()
I end up with double-slashes, instead of a proper UNC path, and the code
now fails to compile. File:
\\\\a\\b\\c
i.e. the code includes a #include which now fails:
#include "\\\\a\\b\\c\file.h"
How do I stop python from auto-escaping my environment variable?
This appears to be a problem with quoting and dequoting in tcsh. It has nothing to do with Python -- Python gets the same variable that you can print out with the env command.
It appears that in tcsh, echo $FOO de-quotes the value of $FOO before printing. This seems to have misled you about what is really in your environment variable, so you've added an extra layer of quoting.
unaha-closp:~> setenv FOO "\\hello\world"
unaha-closp:~> echo $FOO
\hello\world
unaha-closp:~> env | grep FOO
FOO=\\hello\world
unaha-closp:~> python
Python 2.7.3 (default, Sep 26 2013, 20:03:06)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> print os.environ["FOO"]
\\hello\world
>>>
unaha-closp:~> bash
svk#unaha-closp:~$ echo $FOO
\\hello\world
The proper setenv command should simply be setenv python_error "\\a\b\c".
Related
After an environment variable is exported and set to empty, I can't get its value in Python with os.environ. Is it expected?
Examples:
## export TEST_ENV_VAR
(base) ➜ Code export | grep TEST_ENV_VAR
TEST_ENV_VAR=''
(base) ➜ Code python
Python 3.8.12 (default, Oct 12 2021, 13:49:34)
[GCC 7.5.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> 'TEST_ENV_VAR' in os.environ
False
## export TEST_ENV_VAR=''
(base) ➜ Code export | grep TEST_ENV_VAR
TEST_ENV_VAR=''
(base) ➜ Code python
Python 3.8.12 (default, Oct 12 2021, 13:49:34)
[GCC 7.5.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> 'TEST_ENV_VAR' in os.environ
True
## export TEST_ENV_VAR='TEST'
(base) ➜ Code export | grep TEST_ENV_VAR
TEST_ENV_VAR=TEST
(base) ➜ Code python
Python 3.8.12 (default, Oct 12 2021, 13:49:34)
[GCC 7.5.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> 'TEST_ENV_VAR' in os.environ
True
The three samples above run in three different new terminals. I modified the .zshrc file to export different values. What's the difference between export foo and export foo=''?
There is a difference between "Shell variables" and "Environment Variables" - see here - A shell variable is only available to the shell setting it whereas an environment variable is available to all child processes as well.
In bash - you can get the list of environment variables with env, and add to the environment variables with export
SHELL_VAR="10"
env | grep SHELL_VAR # No result
export ENV_VAR=100
env | grep ENV_VAR # ENV_VAR=100
Python shell (child process) picks the environment variables when you try an os.environ
'SHELL_VAR' in os.environ # False
'ENV_VAR' in os.environ # True
The issue is the way you are defining your variables.
When you just do:
export FOO
no variable is actually exported unless FOO has been defined previously:
FOO=''
export FOO
or concomitantly:
export FOO=''
If FOO appears in env | grep FOO, it should appear in os.environ.
With Emacs 24.3.1, I get this when editing through Tramp/ssh in eshell:
/<remotepath> $ bash
/<remotepath> $ python test.py
hello world!
/<remotepath> $ exit
exit
/<remotepath> $ python test.py
Python 2.6.6 (r266:84292, Oct 12 2012, 14:23:48)
[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
The file test.py is:
print "hello world!"
Bash is version 4.1.2. Does anyone have any explanation for this behavior?
I don't know eshell, but my guess is you forget to pass the positional parameters when creating your alias:
# don't forget the quotes
# ▼ ▼
~ $ alias python '/path/to/alternate/python $*'
# ▲▲
# don't forget positional parameters
See http://www.emacswiki.org/emacs/EshellAlias
I can get a value n when I run a shell command using os.system in the python script, but I also need to sum it up to get a total number for subsequent computation in the python script,
total=0
for i in xrange(1,8):
os.system('n=$(qstat -n1 | grep -o node'+str(i)+' | wc -l) && echo $n')
Is it possible? Also is it possible to use python variable in shell command, something like
os.system('echo $total')
Use the shell's exportcommand:
$ export ABC=1 # Set and export var in shell
$ bash # Start another shell
$ echo $ABC # variable is still here
1
$ python # Start python still in the deeper shell
Python 2.7.2 (default, Oct 11 2012, 20:14:37)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from os import environ # import environnement
>>> environ['ABC'] # And here's the variable again (it's a string because the shell doesn't have types)
'1'
You can subprocess module's check_output method like this
import subprocess
print sum(int(subprocess.check_output(["/bin/sh", "-c", "n=`expr {} + 1` && echo $n".format(i)])) for i in range(10))
Output
55
Given the following python script....
$ cat readStdin.py
#!/usr/bin/python
import sys
var = "".join(sys.stdin.readlines()).rstrip()
print var
... I get the follwing output:
$ echo hello | python -i readStdin.py
hello
>>>
$
... in other words it does not hang in the python console, but goes back to bash. Does anyone out there know how to make it stay in the python console???
Consider this -
$ echo print 4*2 | python -i
Python 2.7.2 (default, Jun 20 2012, 16:23:33)
Type "help", "copyright", "credits" or "license" for more information.
>>> 8
>>>
$
Echo produces print 4*2. Python even in interactive mode, considers this as input to be interpreted. Hence we see the 8 there. After this, the interpreter encounters an EOF, so it quits. Consider what you press to quit the interpreter - Ctrl+d or ^D. This is just another way to produce EOF on *nix.
I installed Python 2.7 today using:
./configure --prefix=/home/zhanwu/local --enable-shared --enable-profiling --with-pydebug
make install
Then I keep getting something like "[37745 refs]" on screen after each function call:
[zhanwu#cluster ~]$ ~/local/bin/python
Python 2.7.1 (r271:86832, Jun 16 2011, 17:45:05)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
[37745 refs]
>>> print 'test'
test
[37745 refs]
>>> sys.exit()
[18048 refs]
[zhanwu#cluster ~]$
What does those numbers mean? Anything wrong here and can I get rid of them?
uname -a result:
[zhanwu#cluster ~]$ uname -a
Linux cluster.xxx.xxx.xxx 2.6.18-128.1.14.el5 #1 SMP Wed Jun 17 06:38:05 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
You get these because you configured the build with --with-pydebug. They denote the number of references Python is currently keeping track of. To get rid of them, configure without --with-pydebug.