How to display bash special characters \h, \s, etc - linux

I can't find a way to display bash special chars. For example the hostname is \h.
If I do :
echo '\h \\h'
it won't work ( display h \h). How can I make it display my hostname ?
ref : http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/bash-prompt-escape-sequences.html

Those are only evaluated in the PS1 and PS2 variables. You can test them dynamically like this:
PS1="\h"
The bash will then display the new prompt. Just open a new bash if you mess it up, it will not be saved.

The HOWTO told you it is "Prompt Escape Sequences", only works when you put then in PS1 or PS2,

Related

Bash prompt variables does not work inside a bash function

I'm working on a prompt customization, but for some reason, when I use the \u, \h and \W variables as is it works perfectly, but when I put them inside a function, they are displayed as "\u" or "\W" instead of their values.
...
print_user()
{
echo -e "\001\u\002#\001\h\002"
}
print_dir()
{
echo -e "\001${YELLOW}\002\001\W\002\001${RESET_ATTR}\002"
}
PS1='[$(print_user) on $(print_dir)] $(get_git_repo) \001\n\002$(print_prompt) '
This displays as:
[\u#\h on \W]
>
If I move them outside of the function like so
PS1='[\[\u\]#\[\h\] \[${YELLOW}\]\[\w\]\[${RESET_ATTR}\]] $(get_git_repo) \[\n\]$(print_prompt)'
It works fine, and displays the current directory with the username and hostname:
[myusername#arch on ~]
>
Is this just how bash works? Is there a different way of doing it so it will work? Why is it that inside of a function it won't display the variables' values but outside of a function it does?
From the man page, under PROMPTING
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, subject to the value of the
promptvars shell option (see the description of the shopt command under SHELL BUILTIN COMMANDS below).
By the time the shell expands $(print_user) to add \u to the string, it is too late to decode it, so the literal string \u remains in the prompt.
One alternative is to use PROMPT_COMMAND to execute a function that defines PS1 dynamically, just before it is displayed, instead of embedding command substitution in the value of PS1 itself.
make_prompt () {
PS1="[$(print_user) on $(print_dir)] $(get_git_repo)"
PS1+='\[\n\]'
PS1+="$(print_prompt) "
}
PROMPT_COMMAND=make_prompt
Now, print_user will have been called before the shell decodes the value of PS1, by which time all the prompt escapes will be present.

Where and How Bash convert strings to colors

I am working on Bash 5.0 from GNU repository. I wanted to find the place where Bash reads a string with ASCII colors and convert it to colors, like in the following case where it convert "Hello" to red:
root#ubuntu:~/Desktop/bash-5.0# ./bash
root#ubuntu:~/Desktop/bash-5.0# echo $BASH_VERSION
5.0.0(8)-release
root#ubuntu:~/Desktop/bash-5.0# ./bash -c 'echo -e "\033[31mHello\e[0m World"'
Hello World
I searched inside the source code and found two files that seems to be related:
bash-5.0/lib/readline/colors.c - link
bash-5.0/lib/readline/parse-colors.c - link
But they are not, they work only on the first time I load Bash and you need to write the following rows in the file ~/.inputrc for it to work:
set colored-completion-prefix on
set colored-stats on
Any idea where in the code Bash takes string like that "\033[31mHello" and convert it to red?
It's not the shell that's converting anything to colors, it is your terminal. The shell only outputs ANSI escape codes which are then picked up by the terminal.
Depending on your point of view and philosophical interpretations, \033[31mHello already is a colored string (for the shell, at least, it is)

What's the default encoding in bash standard input? [duplicate]

I am using Gina Trapiani's excellent todo.sh to organize my todo-list.
However being a dane, it would be nice if the script accepted special danish characters like ø and æ.
I am an absolute UNIX-n00b, so it would be a great help if anybody could tell me how to fix this! :)
Slowly, the Unix world is moving from ASCII and other regional encodings to UTF-8. You need to be running a UTF terminal, such as a modern xterm or putty.
In your ~/.bash_profile set you language to be one of the UTF-8 variants.
export LANG=C.UTF-8
or
export LANG=en_AU.UTF-8
etc..
You should then be able to write UTF-8 characters in the terminal, and include them in bash scripts.
#!/bin/bash
echo "UTF-8 is græat ☺"
See also: https://serverfault.com/questions/11015/utf-8-and-shell-scripts
What does this command show?
locale
It should show something like this for you:
LC_CTYPE="da_DK.UTF-8"
LC_NUMERIC="da_DK.UTF-8"
LC_TIME="da_DK.UTF-8"
LC_COLLATE="da_DK.UTF-8"
LC_MONETARY="da_DK.UTF-8"
LC_MESSAGES="da_DK.UTF-8"
LC_PAPER="da_DK.UTF-8"
LC_NAME="da_DK.UTF-8"
LC_ADDRESS="da_DK.UTF-8"
LC_TELEPHONE="da_DK.UTF-8"
LC_MEASUREMENT="da_DK.UTF-8"
LC_IDENTIFICATION="da_DK.UTF-8"
LC_ALL=
If not, you might try doing this before you run your script:
LANG=da_DK.UTF-8
You don't say what happens when you run the script and it encounters these characters. Are they in the todo file? Are they entered at a prompt? Is there an error message? Is something output in place of the expected output?
Try this and see what you get:
read -p "Enter some characters" string
echo "$string"

What does this PROMPT_COMMAND do?

I have this in /etc/bash.bashrc on my Linux system:
PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'printf "\033]0;%s#%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
From man bash I understand that it sets a command to be executed prior to issuing each prompt, but I'm wondering what exactly it's doing.
Basically, it updates the title of the terminal after every command you issue to reflect the current values of the envariables, using XTerm escape sequences.
Some of the escape sequences recognized by XTerm-compatible terminal emulators:
ESC]0;stringBEL — Set icon name and window title to string
ESC]1;stringBEL — Set icon name to string
ESC]2;stringBEL — Set window title to string
where ESC is the escape character (\033), and BEL is the bell character (\007).
Sets your prompt to be whatever is being executed now in addition to a printf that will show your username # your hostname with your present working directory. You'll have to look up the \033]0; terminal code yourself.

change multiple files commandline

I have separated some tracks from mp3 mixes using mp3splt.
BASH: (mp3splt -c('**!!***use .cue file***!!**') [cuefile.cue] [nonstopmix.mp3] ~for anyone interested, is in the Ubu repos~)
And I ended up with these filenames: "Antares" - 01 - "Xibalba".mp3 which is not a format I prefer, now I've made it a little project to change them with a shell script but its more difficult than I anticipated.
I want to change the filename from:
"Antares" - 01 - "Xibalba".mp
to:
01-Antares_-_Xibalba.mp3
so far I've used :
for var in *.mp3; do mv $var {var/"/}; done
and I could repeat that until I'm through, delete the 0x number and add one but I'd like to do it more efficient.
Could anyone give me a pointer (!not a script!) ?
I'd still like to write it myself but there's so much options that I'm a bit lost.
so far I thought to use this program flow:
read all the filenames containing .mp3 and declare as variable $var
strip $var from quotes
select 0x number, append delimiter _ (0x_)
move 0x_ to the beginning of the string
select remaining ' - - ' and change to '-'
done
which bash programs to use? especially changing the 0x puzzles me cuz I need a loop which increments this number and test if it is present in the filename variable and then it has to be changed.
It is easy to do in python 2.x. You can use this logic in any language you want.
import string
a=raw_input('Enter the name of song')
a=a.replace('"', "")
a=a.replace('.mp', ' .mp3')
words = a.split()
print words[2]+'-'+words[0]+'_-_'+words[4]+words[5]
Logic:
I removed ", then make .mp to .mp3, then splitted the string, which created a list ( array ) and then printed the elements according to need.
Try doing this :
rename -n 's/"(\w+)"\s+-\s*(\d+)\s*-\s*"(\w+)"\.mp/$2-$1_-_$3.mp3/' *mp
from the shell prompt. It's very useful, you can put some perl tricks like I does in a substitution.
You can remove the -n (dry-run mode switch) when your tests become valids.
There are other tools with the same name which may or may not be able to do this, so be careful.
If you run the following command (linux)
$ file $(readlink -f $(type -p rename))
and you have a result like
.../rename: Perl script, ASCII text executable
then this seems to be the right tool =)
If not, to make it the default (usually already the case) on Debian and derivative like Ubuntu :
$ sudo update-alternatives --set rename /path/to/rename
Last but not least, this tool was originally written by Larry Wall, the Perl's dad.

Resources