What does "-c" mean in this linux shell command? - python

It's from a tutorial on the google cloud platform, they call python from the Linux Shell.
I'm totally new to gcp and linux, please help me, where can I find some exhaustive documentation for python tools in Linux?
python -c 'import base64, sys, json; \
img = base64.b64encode(open(sys.argv[1], "rb").read()); \
print json.dumps({"key":"1", "image_bytes": {"b64": img}})' \
flower1.jpg > request.json

-c stand for cmd which allows you to pass your code as a string.
This feature is available even outside of google-cloud-platform.
you can check other available options using python -h

the -c flag means execute the following command as interpreted by this program.
Doc: https://askubuntu.com/questions/831847/what-is-the-sh-c-command

When called with -c command, it executes the Python statement(s) given as command. Here command may contain multiple statements separated by newlines. Leading whitespace is significant in Python statements!

Related

How to import a module at each execution of python?

I need to run the command import numpy as np each time I run python. How to automatize it in linux. In other words, how do load a module each time python is launch with having to manually call it?
The -i flag can help with that. See man python.
-i When a script is passed as first argument or the -c option is
used, enter interactive mode after executing the script or the
command. It does not read the $PYTHONSTARTUP file. This can be
useful to inspect global variables or a stack trace when a script
raises an exception.
So the below does what you want it to. Note that the -i flag needs to precede the -c otherwise it doesn't work.
python -i -c 'import numpy'

Odd output when trying to set up Flask secret key

I'm trying to work out how to deploy a Flask app. The docs say I can generate a secret key with a Python command:
python -c 'import os; print(os.urandom(16))'
In their example this outputs b'_5#y2L"F4Q8z\n\xec]/'.
When I run it with python I get odd characters, and with python3 I get character codes. Why are the python and python3 versions different? Which one should I use?
$ python -c 'import os; print(os.urandom(16))'
��L���vl�6��Z5
$ python3 -c 'import os; print(os.urandom(16))'
b'A\xa4\xf3O\xdd\xf4qr\xfb\x9b\x12\x1f*\x0bm\xdf'
You should be using Python 3 for all new projects, so this is essentially a non-issue. The Python 3 output is correct and can be copy pasted directly. The fact that python runs Python 2 for you means you have not followed the tutorial to set up a Python 3 virtualenv, or your virtualenv is not active.
If you're really using Python 2 for some reason, that output is fine too. Copy and paste it into quotes and it will work. Python 2's str is sort-of-bytes, so it outputs non-ASCII characters, while Python 3 always outputs bytes with escape characters (\xAB). Either output will work in either version.
SECRET_KEY = '��L���vl�6��Z5'
SECRET_KEY = b'A\xa4\xf3O\xdd\xf4qr\xfb\x9b\x12\x1f*\x0bm\xdf'
The example output does contain escape characters (\n and \xec), just not as many as the random string you happened to generate.

Can a batch file execute commands within a python shell?

Can I use a batch file to start a python shell and execute commands? I know that
python
will start a python shell, but a batch file containing
python
1+1
will first run python, and then only when you quit python will it attempt to run 1+1. It will not execute any commands within the python shell.
After a little searching around, I managed to find this website that has a method to do this. As you will see on the website, all you need to do is:
#setlocal enabledelayedexpansion && python -x "%~f0" %* & exit /b !ERRORLEVEL!
#start python code here
print "hello world"
This didn't work for me, however I thought it might help.
I haven't been able to find any other source that says it's possible.
Just thought of something else that I haven't tested. I combined Bear's answer and mine.
#for /f "skip=1 delims=" %i in (%0) do #python -c "%i"
#Start Python here.
However, the other method should be used.
I know this has an accepted answer but you might also try the -c argument for the python command. python -c "print(1+1)" will print "2" to the console. The -c flag means "command" and is interpreted by python immediately.

How to start a Python ipython shell, automatically run inside it a few commands, and leave it open?

I tried
echo "print 'hello'" | ipython
Which runs the command but ipython immediately exits afterwards.
Any ideas? Thanks!
Edit:
I actually need to pass the command into the interactive Django shell, e.g.:
echo "print 'hello'" | python manage.py shell
so the -i switch gimel suggested doesn't seem to work (the shell still exits after execution)
Use the same flag used by the standard interpreter, -i.
-i
When a script is passed as first argument or the -c option is used, enter interactive mode after executing the script or the command, even when sys.stdin does not appear to be a terminal. The PYTHONSTARTUP file is not read.
A Linux example, using the -c command line flag:
$ ipython -i -c 'print "hello, ipython!"'
hello, ipython!
In [2]: print "right here"
right here
In [3]:
Try using the ipy_user_conf.py inside your ~/.ipython
I'm not sure of ipython but the basic python interpreter has a command line parameter to give you the prompt after it executes the file you've given it. I don't have an interpreter handy to tell you what it is but you can get it using python --help. It should do exactly what you want.
Running a custom startup script/profile script with the Django shell was marked as closed: wontfix.
However, there is a shell_plus Django extension discussed in that ticket which seems to do what you want. I haven't had a chance to check it out, but it looks like at the very least it can run a load to auto import all the models of all installed apps (which I usu. find myself doing).
Shell plus.py in django-command-extensions on Google Code
django-command-extensions homepage on Google Code
django_extensions on Github

Cannot pass an argument to python with "#!/usr/bin/env python"

I needed to have a directly executable python script, so i started the file with #!/usr/bin/env python. However, I also need unbuffered output, so i tried #!/usr/bin/env python -u, but that fails with python -u: no such file or directory.
I found out that #/usr/bin/python -u works, but I need it to get the python in PATH to support virtual env environments.
What are my options?
In some environment, env doesn't split arguments.
So your env is looking for python -u in your path.
We can use sh to work around.
Replace your shebang with the following code lines and everything will be fine.
#!/bin/sh
''''exec python -u -- "$0" ${1+"$#"} # '''
# vi: syntax=python
p.s. we need not worry about the path to sh, right?
This might be a little bit outdated but env(1) manual tells one can use '-S' for that case
#!/usr/bin/env -S python -u
It seems to work pretty good on FreeBSD.
It is better to use environment variable to enable this. See python doc : http://docs.python.org/2/using/cmdline.html
for your case:
export PYTHONUNBUFFERED=1
script.py
When you use shebang on Linux, the entire rest of the line after the interpreter name is interpreted as a single argument. The python -u gets passed to env as if you'd typed: /usr/bin/env 'python -u'. The /usr/bin/env searches for a binary called python -u, which there isn't one.
Passing arguments to the shebang line is not standard and in as you have experimented do not work in combination with env in Linux. The solution with bash is to use the builtin command "set" to set the required options. I think you can do the same to set unbuffered output of stdin with a python command.
my2c
Here is a script alternative to /usr/bin/env, that permits passing of arguments on the hash-bang line, based on /bin/bash and with the restriction that spaces are disallowed in the executable path. I call it "envns" (env No Spaces):
#!/bin/bash
ARGS=( $1 ) # separate $1 into multiple space-delimited arguments.
shift # consume $1
PROG=`which ${ARGS[0]}`
unset ARGS[0] # discard executable name
ARGS+=( "$#" ) # remainder of arguments preserved "as-is".
exec $PROG "${ARGS[#]}"
Assuming this script is located at /usr/local/bin/envns, here's your shebang line:
#!/usr/local/bin/envns python -u
Tested on Ubuntu 13.10 and cygwin x64.
This is a kludge and requires bash, but it works:
#!/bin/bash
python -u <(cat <<"EOF"
# Your script here
print "Hello world"
EOF
)
Building off of Larry Cai's answer, env allows you to set a variable directly in the command line. That means that -u can be replaced by the equivalent PYTHONUNBUFFERED setting before python:
#!/usr/bin/env PYTHONUNBUFFERED="YESSSSS" python
Works on RHEL 6.5. I am pretty sure that feature of env is just about universal.
I recently wrote a patch for the GNU Coreutils version of env to address this issue:
http://lists.gnu.org/archive/html/coreutils/2017-05/msg00018.html
If you have this, you can do:
#!/usr/bin/env :lang:--foo:bar
env will split :lang:foo:--bar into the fields lang, foo and --bar. It will search PATH for the interpreter lang, and then invoke it with arguments --foo, bar, plus the path to the script and that script's arguments.
There is also a feature to pass the name of the script in the middle of the options. Suppose you want to run lang -f <thecriptname> other-arg, followed by the remaining arguments. With this patched env, it is done like this:
#!/usr/bin/env :lang:-f:{}:other-arg
The leftmost field which is equivalent to {} is replaced with the first argument that follows, which, under hash bang invocation, is the script name. That argument is then removed.
Here, other-arg could be something processed by lang or perhaps something processed by the script.
To understand better, see the numerous echo test cases in the patch.
I chose the : character because it is an existing separator used in PATH on POSIX systems. Since env does PATH searching, it's vanishingly unlikely to be used for a program whose name contains a colon. The {} marker comes from the find utility, which uses it to denote the insertion of a path into the -exec command line.

Categories