Bash terminal command worries - python

I have recently become the owner of a MacBook.
Due to this and my programming I have been using the terminal a lot.
I was bored so decided to mash my keyboard and ended up with an input of
agr'l
This was fine until it brought about the start of the line being > and it waiting for an input. Also at the beginning and the end of the line it has squared brackets as if they are bing held together
Any help that could be given on what this is would be appreciated.
Many Thanks

In the common Bourne compatible Unix shells (sh, ksh (Korn shell), bash, and zsh, among others) the shell will allow continuation of lines which contain unmatched quotation marks or other delimiters (such has parentheses for blocking commands with a subshell or {curly;braces} for grouping statements together). Also lines ending in a backslash \ character will be continued.
In these cases the shell will display your $PS2 prompt string (the one you're using to seeing is $PS1 ... "prompt string: primary" vs. the "prompt string: secondary." There are a couple of other $PS_ environment variable for prompting generated by a call to the select built-in and for the output lines from tracing execution of a shell script (using the set -x command, or the -x command line option to the shell).
Read the man pages and search on PS1 through PS4 to learn more about each one.

Related

python subprocess.call not showing certain characters

I'm trying to call tree in python with subprocess.call but instead of returning "│" it only returns "�", this also happens with os.system.
using python 3
windows 10
This is the horror of working with character sets in Windows. The application is printing out one of the line-drawing characters. In the MS-DOS code page, that's probably 0x10. Depending on how your terminal is set up, that might print as a vertical line, or it might print as something else. If the app has the option to print out ASCII art ( + - | ), that will be more universal.
I kinda found out how to fix it, it depends where I run the script from, when I run it from the IDE i get the strange "�" character when I run it from the python console I get nothing but when I run it from cmd I get the right output.

How to run multple lines of python code from shell, instead of from a script

I want to run python code from the shell instead of from a script.
I searched everywhere and found suggestions about using echo or Shift+Enter and using ^ at the end of the line, but ^ and shift+Enter didn't work in python shell, and I need to if there is a way to separate commands in the shell.
For example I need to run this from python shell instead of from a script:
If x > y
print ("x is greater than y.")
but non of the options I tried worked.
You need to use : to issue a line separator.
i.e.
if x > y:
print ("x is greater than y.")
If you are asking how to enter Python code in your shell, then try something like
python -c 'if x > y:
print(("x is greater than y")'
assuming you are using a Bourne-compatible shell (Linux etc). This has the major drawback that your Python code cannot easily contain a single quote (though if you know the quoting rules of the shell it's of course not impossible or even unobvious how to create an expression which evaluates to a single quote).
However, the common way to do this (and perhaps the only way on Windows?) is to type the Python code into a file and then run it with
python filename.py
where filename.py is the name of the file where you saved your Python code.
You can of course run simply
python
to enter the Python interpreter in interactive mode, where you can type in Python expressions and have them evaluated immediately. When you type an expression which ends with a colon, Python changes the prompt from >>> to ... to indicate that it expects one or more indented lines. (Type just a newline immediately at the ... prompt to exit this mode.)

Python + bash prompt: how to print width calculation wrappers?

I wrote a Python script to replace "powerline" as a terminal prompt solution for myself here: https://github.com/diogobaeder/dotfiles/blob/master/.bash_prompt.py
Then all I do is to define the prompt from the output of that script:
# in my ~/.bashrc
export PS1="\$(python ~/.bash_prompt.py)"
The script itself works fine, I get the command prompt I want; However, since there's no wrapping for the styles I put there, the terminal (doesn't matter which GUI terminal program I use) doesn't calculate the prompt width correctly, and as I type characters after the prompt it ends up not wrapping them to a new line at first, overwriting the prompt completely.
Now, I know that when stylizing my bash prompt I need to escape style codes with \[ and \] so that bash takes into consideration that they're escape sequences and calculates the width correctly. However, if I put them as wrappers for my styles in my Python script (see esc_start and esc_end), I can't get them to be properly evaluated by bash as "calculation escape sequences", instead I get literal square brackets printed. If I then escape in Python the backslashes too (\\[ and \\]), then I get unescaped literals outputted (\[ and \]). Bash seems to completely ignore them as escape sequences for calculating the prompt width.
If, however, I remove the backslash in my PS1 command ($(python ~/.bash_prompt.py) instead of \$(python ~/.bash_prompt.py)), then putting \[ and \] as escape sequences in my Python script (as esc_start and esc_end), then bash considers them as proper escapes and ends up wrapping lines as expected (i.e., when I go past the right border it wraps the line as expected). The problem with this, however, is that removing this backslash from my PS1 definition in .bashrc makes the script run only once per terminal session, and not for each prompt line - so, for example, if I'm in a Git working tree and I change from one branch to another, it doesn't show the new branch as soon as the command finishes, instead it shows the old branch.
Let me give some examples of what I mean, that you can try in your own .bashrc without needing my Python script:
PS1="\[\033[31m\]\u#\h\[\033[0m\]$ " # This wraps lines correctly
PS1="\033[31m\u#\h\033[0m$ " # This makes the line overwrite the prompt
So, any ideas of how to cope with bash and make it understand the \[ and \] sequences correctly when printed by the Python script, while still keeping the script running for each command prompt? Or, if this is a limitation in bash, is there another way to force it to wrap the line when it reaches the right border of the terminal window?
Thanks!
Diogo
[EDIT] Solution (thanks, Grisha Levit!):
This is my bashrc line now:
PROMPT_COMMAND='PS1="$(python ~/.bash_prompt.py)"'
And I re-added the escapes (\[ and \]) to my script, and now it works perfectly! :-)
Bash first interprets the escape sequences in $PS1 and only afterwards handles command substitution, etc.
Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded as follows [...]
After the string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal [...]
--Bash Reference Manual: Controlling the Prompt
This means that any special sequences printed by your command will not be interpreted as colors, etc. The solution is to use $PROMPT_COMMAND to change the value of $PS1, like:
PROMPT_COMMAND='PS1=$(python ~/.bash_prompt.py)'

Entering multiple lines of code to be run later at the Python REPL [duplicate]

This question already has answers here:
Python, writing multi line code in IDLE
(7 answers)
Closed 6 years ago.
I just picked up a basic book today on programming. The coding language is Python and I have only been trying this out for a few hours but I'm already stuck, because I can't figure out how to write multiple lines of code. For example, when I write print("one") and then hit enter, it just runs it and prints the word, one. How can I have it print the word, one, and then the word, two, on the line below it? Also, when I hit tab it just moves over 4 spaces, or so. I can't figure out how to have it not run the first command, and just give me '>>>' on the next line. So I guess what I'm asking is: What keystrokes do I need to use to get something like:
>>> print("one")
>>> print("two")
Thanks so much!
(Sorry for such a basic question, but I'm totally confused on this one.)
The Python REPL automatically executes each command as soon as it is completely typed in. This is why it is called a "read-eval-print loop". It accepts one input, evaluates it, and then prints the result.
If you want to execute two complete commands at once, you can put a semicolon between them, like this:
print("one"); print("two")
I said "completely typed in" above, because some commands inherently require multiple lines, so Python must accept several lines of input before the command is "completely typed in". Three types of command work like this: flow-control commands (def, while, if, for, etc., which apply to several indented lines below them), multiline expressions (calculations inside parentheses or brackets), or statements that use a backslash (\) at the end of the line to indicate that it is continued on the next line. So if you type in any of the blocks below, Python will wait until the block is completely finished before evaluating it.
if 1 + 1 == 2:
print "True"
else:
print "False"
print(
1 + 1
)
print \
1 + 1
You could also combine these two strategies and type something like this:
print("one"); \
print("two")
Python will wait for both commands to be typed and then run them both at once. But I've never seen anyone write code that way.
Alternatively, you could type several commands together in a different text editor, and then paste them into the Python REPL, e.g., copy and paste the following into your REPL (but you will get results printed between the commands):
print("one")
print("two")
Alternatively, you can probably get almost exactly the behavior you were originally expecting by using a different interface to Python. The IPython Notebook is a good choice, or you could try the Spyder or PyCharm editors, which let you select a few lines of code and run them.
Or, if you have a longer script that you want to run all at once, the best option is to type it up in a text file (e.g., script.py), and then tell python to run it, e.g., type python script.py from a system command prompt (not the Python interpreter), or press F5 in the IDLE editor.
One thing you may want to try is writing your code in a file, say learning.py, and then running that file on the command line with python learning.py.
The best way to get better support for multi line commands in python with a "console" feel is to use ipython qtconsole, or Jupyter qtconsole as its now called: http://jupyter.org/qtconsole/stable/. When using qtconsole, hitting Ctrl-Enter will delay the command from running even if it's not a complex block. You can keep hitting Ctrl-Enter as many times as you want, and then hit Enter to run them all. Hitting up arrow will then bring up the whole block again to edit, cleanly indented unlike the regular ipython console.
Note: this is not ipython notebook, nor the regular ipython console, but a separate thing from either using the same kernel. The qtconsole has some other nice things like better syntax highlighting and inline plotting compared to the terminal.

Python: os.system to execute meld command doesn't work in Windows

I am writing a sublime plugin in Python. But I am still very new to Python language. I am using this line to call meld in Python:
if meld_cmd == None:
meld_cmd = "C:\\Program Files (x86)\\Meld\\meld\\meld"
os.system('"%s" "%s" "%s" ' %(meld_cmd, source_name, dest_name))
It doesn't work well in Windows. The cmd window just flashes for a sec (seem to execute something) then disappears. I print the executed string out in sublime and copy the string into cmd window and execute. It executes well in both admin and non-admin mode. And I tried to add a pause before executing:
os.system('pause && "%s" "%s" "%s" ' %(meld_cmd, source_name, dest_name))
This works well too after clicking enter after the press any key to continue... line.
Not sure how to debug this and what is the reason why it is failing.
cmd.exe /c command has a parsing quirk when the command starts with a quote and has more than two quotes. The exact rules are explained in the online help text available via cmd /?:
If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:
1. If all of the following conditions are met, then quote characters
on the command line are preserved:
- no /S switch
- exactly two quote characters
- no special characters between the two quote characters,
where special is one of: &<>()#^|
- there are one or more whitespace characters between the
two quote characters
- the string between the two quote characters is the name
of an executable file.
2. Otherwise, old behavior is to see if the first character is
a quote character and if so, strip the leading character and
remove the last quote character on the command line, preserving
any text after the last quote character.
To get around this, just wrap the whole command in quotes, e.g. '""%s" "%s" "%s""' % (meld_cmd, source_name, dest_name).
Probably the problem is that you need to execute that script with Admin privileges.
Proceed to question How to run python script with elevated privilege on windows to get more information on that topic.

Categories