When i try to set my terminal window title:
$ echo -n "\033]0;foo\007"
\033]0;foo\007
It just print plain text, the terminal title had no change. How to fix it?
You're missing the -e to echo which tells it to interpret backslash escape sequences. Try this:
$ echo -en "\033]0;foo\007"
Although #chris-page is correct about -n being non-standard, the bash builtin echo and the system /bin/echo both support -n. However, the system echo does not support -e which is the real import feature when trying to send those escape codes to the terminal.
Also be aware that the system wide /etc/bashrc sets PROMPT_COMMAND to the function update_terminal_cwd, which is defined as:
update_terminal_cwd() {
# Identify the directory using a "file:" scheme URL,
# including the host name to disambiguate local vs.
# remote connections. Percent-escape spaces.
local SEARCH=' '
local REPLACE='%20'
local PWD_URL="file://$HOSTNAME${PWD//$SEARCH/$REPLACE}"
printf '\e]7;%s\a' "$PWD_URL"
}
And apparently the operating system code 7 for Apple's Terminal.app sets a special icon link to the current working directory. You can right click on the folder icon in the title bar to open Finder at that location. This code also modifies the title bar title a bit by prepending the last component of the current working directory.
I've been investigating how Terminal.app's tab titles vs title bar title are set. And apparently they follow along with xterm's pretty well, where 'icon name' is the tab title, and 'window title' is the title bar title.
The title bar title is whatever you set with osc-2 (or osc-0). If the extra path component is set by osc-7 it will be prepended to the title bar title. And if any components are checked in Preferences->Settings->Window, they will be appended to the title bar title.
The tab title is whatever you set with osc-1 (or osc-0). If that is unset, it will be the contents of the Title box of Preferences->Settings->Window with the active process name appended. If the title is exactly Terminal (whether set by the text box in preferences or by osc-1) the tab title will just be the active process name.
Bash’s built-in echo command no longer† supports the -n option, because it’s not a POSIX option. Instead, use the printf command to send control characters: printf '\033]0;foo\007’.
In general, it’s better practice to use printf for consistent results instead of echo for anything more complicated than printing strings with ASCII graphic characters, because POSIX echo is fairly simple and any extended behaviors may vary between shells.
† I don’t recall exactly which OS version it changed, but it’s unsupported in 10.8.
Related
How do you display Regional Status Indicators (things like country flags) in the Linux Terminal? Is this even possible?
I'm programming a VPN client and would like to include some flags for the countries the client includes. For example, I would like to display the Japan flag (🇯🇵). I pasted the two Unicode symbols 🇯 and 🇵 next to each other in a Bash script, but upon running the script in the Terminal, I just got the two symbols next to each other (they didn't "merge"). For example purposes I have part of the file below (note there is a space between the symbols so they don't "merge" in the browser, the space is not there in the real script).
#!/bin/bash
echo "Please choose a server:"
echo -e "🇯 🇵 Japan (1)" # in the real script there is no space here.
echo -e "..."
read -p "> " choice
...
And upon running:
$ ./script.sh
Please choose a server:
🇯 🇵 Japan (1) [ with no space in between ]
...
I understand the concept of Regional Status Indicators, but my question is if it's possible to use them in the terminal.
Edit: I noted that some answerers were having trouble understanding my problem, so I provided a screenshot of what my terminal looks like when I run this script.
Not sure if you copied the correct byte sequences, but you can simply use the correct escapes instead:
$ echo -e "\U1f1ef\U1f1f5 Japan (1)"
🇯🇵 Japan (1)
It may also be an issue with your terminal understanding the Unicode sequence and rendering it properly, rather than a problem with your script.
I work in Windows 10 and usually I have up to 5 CMD windows open. I work this way because I need to run the same application with different data and keep monitoring if any exception is thrown.
I set a number as the window's title (using the title command) instead of the default text, in order to easily identify which window I'm working in and be able to identify and change between them using Alt+Tab (an example of how I work with my CMD windows)
Recently I started to use Git and I really like the Git Bash terminal for Windows. I would like to work with Git Bash terminal the same way I work with CMD windows, but I can't find any way to change the window title. I searched a bit and found these instructions and some others (that I can't paste because I'm not allowed to post more than two links yet), but it seems to work only by setting a different default title. I'd like to change the window title to any custom text I choose, at any moment.
Is this possible? Is there a command like title available for Git Bash?
A simple option is echo -ne "\e]0;YOUR TITLE HERE\a".
This thread is a few months old. But I think an alternative will be helpful
You can add following line to .bashrc file in your user profile folder
export TITLEPREFIX="Git Bash"
where you want Git bash to be your title prefix. This is user specific change. So if a machine is used by multiple users with their own logins, everyone can customize their own title.
You were on the right track with this link
If you modify the git-prompt.sh script a bit (for me, this is located in c:\Program Files (x86)\Git\etc\profile.d\git-prompt.sh), you can make the title anything you want.
Note: You will need to run VS Code, Notepad++ or similar as administrator to write back to this directory.
First, save a backup of git-prompt.sh (like git-prompt.backup.sh), then modify the start of git-prompt.sh as follows:
if test -z "$GITTITLEPREFIX" # if not empty
then
GITTITLEPREFIX="Git-Bash => " # prefix that will have current pwd appended after it
fi
if test -f ~/.config/git/git-prompt.sh
then
. ~/.config/git/git-prompt.sh
else
if test -n "$GITTITLE"
then ##### Set window title directly to GITTITLE if not empty
PS1='\[\033]0;$GITTITLE\007\]'
else ##### Set window title to GITTITLE PREFIX plus the PWD
PS1='\[\033]0;$GITTITLEPREFIX${PWD//]^[:ascii:]]/?}\007\]'
fi
fi
###### Leave the rest of the file the same
PS1="$PS1"'\n'
PS1="$PS1"'\[\033[32m\]'
###### Etc.
This will first check if GITTITLEPREFIX is empty, and if not, it will set it to "Git-Bash => " similar to in the linked article. This will have the current path appended after it, so if you want "1 : $PWD", then set GITTITLEPREFIX to "1 : " like this:
GITTITLEPREFIX="1 : "
Otherwise, you can set GITTITLE to any non-empty value, and then the entire title will be set exactly to the contents of GITTITLE (no PWD appended), so if you just want "1", use this:
GITTITLE="1"
Then run the script. With my path, I did it like this:
. "/c/Program Files (x86)/Git/etc/profile.d/git-prompt.sh"
and the title should change. Of course, you can alias this or make a separate script from it in a location that is in the path so running it is much simpler, and the title could just be an argument. I'll leave that as an exercise for the reader...
In JSON setting write for Git Console:
"name": "Git Bash",
"tabTitle": "Git Bash",
"suppressApplicationTitle": true
You could use
export MYTITLE=abcd; export PS1=$(echo $PS1 | sed -r "s/(0;).*?(\\\\007)/\1$MYTITLE\2/")
It find regular expression for title and replace it with $MYTITLE.
I could be wrong but I assume title is something between 0; and \007 in $PS1. It work for me.
Or you could add next function to your .bashrc (or .bash_profile)
ttt() {
# change title in gitbash
export PS1=$(echo $PS1 | sed -r "s/(0;).*?(\\\\007)/\1$1\2/")
}
and then anytime use ttt "new title"
I solved my question making very little modifications to the script.
The first one, to pass the name I want for the window, I added the variable name=$1 and set it in the title variable:
name=$1
PS1='\[\033]0;$name\007\]' # set window title
The second one, as recommended here, I commented the next lines:
#PS1="$PS1"'\[\033[35m\]' # change to purple
#PS1="$PS1"'$MSYSTEM ' # show MSYSTEM
The final code is below:
if test -f /etc/profile.d/git-sdk.sh
then
TITLEPREFIX=SDK-${MSYSTEM#MINGW}
else
TITLEPREFIX=$MSYSTEM
fi
name=$1
PS1='\[\033]0;$name\007\]' # set window title
PS1="$PS1"'\n' # new line
PS1="$PS1"'\[\033[32m\]' # change to green
PS1="$PS1"'\u#\h ' # user#host<space>
#PS1="$PS1"'\[\033[35m\]' # change to purple
#PS1="$PS1"'$MSYSTEM ' # show MSYSTEM
PS1="$PS1"'\[\033[33m\]' # change to brownish yellow
PS1="$PS1"'\w' # current working directory
if test -z "$WINELOADERNOEXEC"
then
GIT_EXEC_PATH="$(git --exec-path 2>/dev/null)"
COMPLETION_PATH="${GIT_EXEC_PATH%/libexec/git-core}"
COMPLETION_PATH="${COMPLETION_PATH%/lib/git-core}"
COMPLETION_PATH="$COMPLETION_PATH/share/git/completion"
if test -f "$COMPLETION_PATH/git-prompt.sh"
then
. "$COMPLETION_PATH/git-completion.bash"
. "$COMPLETION_PATH/git-prompt.sh"
PS1="$PS1"'\[\033[36m\]' # change color to cyan
PS1="$PS1"'`__git_ps1`' # bash function
fi
fi
PS1="$PS1"'\[\033[0m\]' # change color
PS1="$PS1"'\n' # new line
PS1="$PS1"'$ ' # prompt: always $
MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc
Temporally I made a copy of the script and pasted it on C:, to execute it easily every time I need to change the title, according to my path, as as follows:
$ . /c/changename.sh
I'm still learning about scripting so I could be able to set an alias. As #LightCC said, "I'll leave that as an exercise for the reader..."
Let's say I'm on a fresh install of Debian, Jessie (or Wheezy). As a regular user, I've got the prompt defined in the /etc/bash.bashrc file, eventually override by the one in my /home/foobar/.bashrc
Ok, cool, so I've got something like that: foobar#myserver:~$
Now, I'm trying to understand the code below:
# If this is an xterm set the title to user#host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u#\h: \w\a\]$PS1"
;;
*)
;;
esac
As you can see, the PS1 variable (= the prompt) seems to be overrided again (cause yeah I'm in a xterm). But I can't get why we have another $PS1 on the end of the line!
In order to get this, I've put 3 letters a b c in this line :
PS1="a\[\e]0;${debian_chroot:+($debian_chroot)}\u#\h: \w\a\]b$PS1 c"
And now, I have the strange prompt below:
abfoobar#myserver:~$ c
So it seems that the almost entire line is not use, everything between the brakets.
Is that a sort of conditional statement?
What is really the purpose of this line?
Why the comment talk about the title of the xterm windows but seems
to only override the PS1? I'm running this xterm through PuTTY ; in ubuntu, this line is quite different
PROMPT_COMMAND='echo -ne "\033]0;${USER}#${HOSTNAME}: ${PWD}\007"'
the part between \[ \] seems to be an escape sequence which is handled by terminal : ESC ] which is named OSC for Operating System Commands in following link xterm escape sequence
OSC Ps ; Pt ST
Set Text Parameters. For colors and font, if Pt is a "?", the
control sequence elicits a response which consists of the con-
trol sequence which would set the corresponding value. The
dtterm control sequences allow you to determine the icon name
and window title.
Ps = 0 -> Change Icon Name and Window Title to Pt.
It is to change xterm window title.
As the window title contains the current working directory setting the prompt allows to update the title when changing directory after cd command.
I'm encountering a strange issue in the Terminal app in Mac OS X Lion. When I enter in a long line of text that should wrap to the next line when it reaches the edge of the Terminal window, it continues to type on top of the text from the line above it.
Here are some screenshots to help illustrate the issue:
Before my text reaches the window edge:
After the text reaches the window edge:
I've also supplied screenshots of my text and window settings in case those might be helpful.
Text settings:
Window settings:
Thanks in advance for any assistance offered. I've had this issue for a while and just never got around to it. It's now really becoming a pain in the ass when I get into things that require big grep commands and long path names.
PS1 environment variable determines what shell's prompt will look like. man bash gives full documentation on it. (There are actually several of them, for different modes).
There are number of files that may be setting it, usually one of ~/.profile, ~/.bashrc, /etc/profile or /etc/bashrc.
If you're going to have color codes or other control sequences inside it, you must wrap them with \[ and \] properly (and NOT wrap normal text), otherwise line editing may become messed up like in your case. I suggest resetting PS1 to the default value then carefully adding coloring back item by item.
For example:
PS1='\[\033[1m\033[32m\]\u#\h \w\[\033[0m\]\$ '
^^^^^^^^^^^^^^^ ^^^^^^^
Coloring commands are underlined. Note how they are surrounded with \[ \].
I have the same problem, i found if you change
Advanced > Emulation > Declare terminal as: ANSI.
This solves colored PS1 problem. With Mac Terminal
BUT creates a strange behavior:
I found a solution to my problem with #koiyu answer.
https://apple.stackexchange.com/questions/37001/strange-behavior-in-terminal-with-custom-bash-profile/37036#37036
I used to have the same issue due to incorrectly using color codes. Here is my PS1 which solved the issue. Also if you use GIT, then this will be also helpful to show git branch you are working on and if your working tree is dirty or not. Put this in your .profile or .bash_profile
# Git branch in prompt.
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
parse_git_dirty() {
st=$(git status 2>/dev/null | tail -n 1)
if [[ $st == "" ]]; then
echo ''
elif [[ $st == "nothing to commit (working directory clean)" ]]; then
echo ''
elif [[ $st == 'nothing added to commit but untracked files present (use "git add" to track)' ]]; then
echo '?'
else
echo '*'
fi
}
# coloring the terminal comman line
SB_GREEN="\[\033[1;32m\]"
SB_BLUE="\[\033[1;34m\]"
SB_RED="\[\033[1;31m\]"
SB_NOCOLOR="\[\033[0m\]"
export PS1="$SB_GREEN\u#\h$SB_NOCOLOR: $SB_BLUE\w$SB_GREEN\$(parse_git_branch)$SB_RED\$(parse_git_dirty)$SB_NOCOLOR $ "
Hope this helps.
With the guidance of hamstergene I was able to figure out how to make it play nice. Using this Geek Stuff guide and this It's Me Tommy tutorial, I was able to define how I wanted my PS1 text to display. Changing this to something much more simplified eliminated the weird overlapping text issue I was running into.
Before:
After:
I simply edited my .bash_profile and added the following line:
export PS1="[\u#\h] > ";
Then I went and changed the window colors for good measure because I can.
The original issue was that there was a new line in the PS1 (FYI for anybody running into this)
Typically its improperly escaped color codes, but if its not that its that you have a new line in your ps1
As others have said, you have to properly wrap your color commands in escaped square brackets. However, for me, this makes the string really, really confusing to look at!
As such, here's a trick I use to always get it right and also make it much more readable.
I first create a shell function called setColor like so...
setColor(){
echo "\[\033[${1}m\]"
}
Then I use it like this...
PS1="$(setColor 92)\u$(setColor 37):$(setColor 96)\w $(setColor)\$ "
That's the same as writing this...
\[\033[92m\]\u\[\033[37m\]:\[\033[96m\]\w \[\033[m\]$
...but as you can see, the former is much clearer and also guarantees everything's properly escaped.
Note, you can specify multiple colors too by using the ; character. The only thing is you have to explicitly escape it, so 92;41 becomes 92\;41, like so...
PS1="$(setColor 92\;41)\u$(setColor 37):$(setColor 96)\w $(setColor)\$ "
Again, still easier to read than this...
\[\033[92;41m\]\u\[\033[37m\]:\[\033[96m\]\w \[\033[m\]$
You can take this a step further by defining constants for the colors, or even 'wrapper' functions with the color names you use most, so you can write this...
PS1="$(setRed)\u$(setBlue):$(setGreen)\w $(resetColor)\$ "
Hope this helps!
When I call commands like man, it puts everything into a buffer and only shows one page at a time. I can navigate with my arrow keys or my space bar but I want it to show everything at once without me having to scroll through it. What do I need to do in order to change it? I'm pretty sure it's some key bind but I can't figure it out.
I would prefer it if it would simply just automatically scroll to the end. If there's some command I can enter to make it automatically do this, please let me know. If I have to use a key bind instead to make it scroll down to the end of the buffer, or send everything to the shell, then let me know.
If I'm doing a key bind, I'd prefer it to be something like shift/command + down to scroll all the way down. And then I'd probably map a similar one to go back up.
Thanks.
When you use man, it's piping your result through a pager. If you haven't configured it, on the Mac this is /usr/bin/less -is.
One way to bypass the pager is by setting it to ul. For example:
% man -P ul ls
LS(1) BSD General Commands Manual LS(1)
[...]
ul is a filter that ensures boldface and underlining are preserved. They're encoded in a rather archaic way by X^HX and X^H_ respectively, which modern terminals don't support; pagers ordinarily translate these into terminal escape sequences by themselves.
With man, there are a couple of other options:
In OS X 10.5 and later, you can use
the Help menu to get man pages.
Just press
⇧⌘/
and type the name of the page you
want, then select it from the menu (although I think this uses a
fixed path unfortunately). This
just runs man -P ul for you in a new Terminal window.
Another is to render into
PostScript, which OS X can convert
into a PDF, nicely formatted for
printing if you want. I've been
using this zsh function for years:
gman() {
PDF=/tmp/man.$$.pdf
print 'Converting to PDF...'
man -t $# | /usr/bin/pstopdf -i -o $PDF
print 'Opening...'
open $PDF
{ sleep 5; rm -f $PDF } &!
}
Changing the pager to cat instead of the default (/usr/bin/less -is on my machine) should do what you want. From the man(1) man page:
-P pager
Specify which pager to use. This option overrides the MANPAGER environment variable, which in turn overrides the PAGER variable. By default, man uses /usr/bin/less -is.
'
So you can either do man -P cat whatever, or you can set MANPAGER and/or PAGER in your environment to cat and get the same behaviour.
The less pager which is usually the default on most systems already has key bindings to go directly to the end and start of its input:
g will go to the start of the input
G (which would actually be something along the lines of Shift+g, unless you type with Caps Lock on) will go to the end of the input