Portál AbcLinuxu, 20. května 2024 01:36

Bash prompt: Vzhled a obsah příkazového řádku

17. 3. 2010 | David Watzke
Články - Bash prompt: Vzhled a obsah příkazového řádku  

V tomto článku si povíme a ukážeme, jak nastavit prompt (neboli příkazovou výzvu) v Bashi. Může obsahovat užitečné informace v různých barvách i výstup programů.

Obsah

Aby bylo jasno, o čem bude řeč: Prompt, to je takové to user@localhost $ nebo třeba bash-4.1#, které vidíte v konzoli. Prompt lze nastavit tak, aby zobrazoval (vám) užitečné informace a navíc ještě vypadal dobře, což se vyplatí, trávíte-li v shellu aspoň nějaký čas.

Jak se to dělá? Nastavením proměnné PS1 na požadovanou hodnotu. Chcete-li například, aby výzva obsahovala pouze znak ">", nastavte PS1 takto:

PS1="> "

Aby toto nastavení přetrvalo i po ukončení shellu a použilo se pro další vytvořené shelly, přidejte deklaraci proměnné do souboru ~/.bashrc či ~/.bash_profile, pokud chcete nastavit prompt pouze pro uživatele, pod kterým pracujete, anebo do souboru /etc/bashrc (případně /etc/bash/bashrc, třeba na Gentoo), pokud chcete nastavit prompt pro všechny.

Možnosti

link

Pokud chcete používat takto chudý prompt např. z důvodu nedostatku místa na malé obrazovce mobilu, tak budiž, ale my si dále ukážeme, jak do promptu dostat nějaké užitečné informace. Manuálová stránka Bashe v sekci PROMPTING obsahuje přehled hodnot, které když do PS1 přidáte, tak se automaticky nahradí za požadovanou informaci. Některé z nich si vyjmenujeme a popíšeme:

\h
Název počítače (od začátku k první tečce).
\H
Celý název počítače.
\j
Počet procesů na pozadí daného shellu.
\n
Odřádkování.
\t
Čas ve formátu HH:MM:SS.
\A
Čas ve formátu HH:MM.
\u
Uživatelské jméno.
\v a \V
Verze Bashe (4.1 a 4.1.2).
\w
Aktuální pracovní adresář. Název domovského adresáře (např. /home/dave) je zkrácen na tildu (~).
\W
Vrchní adresář aktuálního pracovního adresáře (jste-li v /tmp/x/y, zobrazí y).
\$
Je-li efektivní UID rovné 0, vloží znak „#“, jinak vloží znak „$“.
\\
Zpětné lomítko.

Předpokládejme počítač s názvem amd64.watzke.cz a uživatelem dave. Ukážeme si několik ukázkových zápisů PS1:

PS1="\u@\h \w \$ "	# bude vypadat takto: dave@amd64 /tmp $
PS1="[\u \H \A \W]\$ "	# [dave amd64.watzke.cz 16:55 tmp]$
PS1="\u [\j]> "		# dave [2]>

Barvy

link

Toto je základní způsob, jak do promptu dostat informace. Teď bychom je mohli ještě obarvit, jelikož to může zlepšit přehlednost a my pak rychleji najdeme tu konkrétní informaci, kterou zrovna hledáme. Obarvení se provádí tak, jak jsem nedávno popisoval v článku Barevný a formátovaný text v terminálu. Akorát je zde jedna maličkost. Přestože to funguje i bez toho, je vhodné přidat před každou escapovací sekvenci \[ a za ní pak \]. Dělá se to z toho důvodu, aby Bash věděl, že jde o „netisknutelné“ znaky (pouze mění formátování, nevloží žádný znak) a nezapočítával je do délky promptu, protože to způsobuje problémy se zalamováním, když zadáte nějaký dlouhý příkaz. Takže třeba červeného textu docílíte takto:

\[\033[31\]Červený text…\[\033[0m\]

Jestli vám zápisy formátování připadaly nepřehledné předtím, teď to celé dostalo nový rozměr. Proto je vhodné uložit si jednotlivé barvy do proměnných a ty pak použít při tvoření PS1.

KONEC="\[\033[0m\]"
TYRKYSOVA="\[\033[36;1m\]"
CERVENA="\[\033[31;1m\]"

PS1="${TYRKYSOVA}\u${KONEC}@${CERVENA}\h${KONEC} \$ " # dave@amd64 $ 

Opět připomínám, že formátování je třeba ukončovat (proměnná KONEC).

Příkazy

link

Tak už umíme sestavit barevný prompt. Je na čase si trochu rozšířit obzory. Jelikož lze do PS1 nacpat opravdu cokoliv a Bash svými speciálními sekvencemi typu \h pochopitelně nepokrývá všech nekonečno možností, je zde proměnná PROMPT_COMMAND. Do této proměnné můžete vložit příkaz, který daný prompt vygeneruje a nastaví. Vhodné je nastavit proměnnou třeba takto:

PROMPT_COMMAND="source $HOME/.prompt.sh"

Ale ještě předtím je třeba vytvořit soubor ~/.prompt.sh, ve kterém se proměnná PS1 nastaví. Může to být bashový skript se vším, co k tomu patří. Například můj prompt vypadá takto:

#!/bin/bash

S=$?

END="\[\e[0m\]"
RED="\[\e[31;1m\]"
CYAN="\[\e[36;1m\]"
GREEN="\[\e[32;1m\]"
YELLOW="\[\e[33;1m\]"

if [[ $S -eq 0 ]]; then
        DOLLAR="${YELLOW}\$"
else
        DOLLAR="${RED}\$"
fi

PS1="${CYAN}\u${END}@${RED}\h${END} ${GREEN}\w${END} ${DOLLAR}${END} "

Vlastně jediným důvodem, proč jsem si vytvářel skript na nastavení PS1, je nastavení barvy znaku dolaru, který je na konci. Barva závisí na návratové hodnotě naposledy spuštěného příkazu. Když je hodnota rovna 0 (příkaz se vykoná s úspěchem), dolar je žlutý, jinak je červený.

prompt konsole

Ovšem pozor na to, vy si můžete vymýšlet daleko víc než já. Můžete si do promptu vložit výpisy z programů a podobně. Nic vám nebrání vložit tam třeba teplotu procesoru:

# tohle je velice specifický zápis (pro konkrétní senzorový čip),
# ale je to tak rychlejší než parsovat výstup příkazu sensors
CPU=$(( $(</sys/devices/platform/it87.656/temp1_input) / 1000 ))

# nastaví CPU_COLOR podle teploty procesoru
if [[ $CPU -gt 60 ]]; then
	CPU_COLOR="$RED"
elif [[ $CPU -gt 50 ]]; then
	CPU_COLOR="$YELLOW"
else
	CPU_COLOR="$GREEN"
fi

# prompt bude vypadat takto: dave@amd64 [57°C
PS1="\u@\h [${CPU_COLOR}${CPU}°C${END}] "

V případě, že se rozhodnete používat PROMPT_COMMAND, stačí tuto proměnnou nastavit v některém ze souborů, kam byste jinak uložili PS1 (viz začátek článku).

Za zmínku stojí ještě proměnná PS2. Řetězec, který drží, se vypíše s každým odřádkováním při psaní víceřádkového příkazu. Výchozí hodnota je "> ".

for((i=0;i<10;i++)); do
> echo "číslo $i"
> done

# pro milovníky pythonního interpreteru
PS2="... "

for((i=0;i<10;i++)); do
... echo "číslo $i"
... done

Pokud používáte xterm, můžete si nastavovat i titulek okna přidáním následující sekvence do proměnné PS1:

\[\033]0;Titulek\007\]

Pro přehlednost to můžete udělat až po nastavení PS1 takto:

case "$TERM" in
xterm*)
	TITLEBAR="\[\033]0;cwd: \w\007\]"
*)
	TITLEBAR=""
esac

PS1="$TITLEBAR\
$PS1"

Jak jsem teď naznačil v kódu, je vhodné kontrolovat, zda jsme v xtermu, nebo ne, protože na VT tato sekvence přidá nesmysly do promptu.

Související články

Barevný a formátovaný text v terminálu
Seriál: Unixové nástroje
Seriál: BASH
Seriál: Nebojíme se kompilace
Regulární výrazy
Bash: chytré doplňování

Odkazy a zdroje

Bash Prompt HOWTO

Další články z této rubriky

Praktický test komprese ZPAQ v programu lrzip
Porovnávání souborů PDF
Microsoft rozdává zadarmo stovky e-knih
Minimalistické prezentace s Markdown
Kde hledat Creative Commons a alternativy

Diskuse k tomuto článku

17.3.2010 00:14 donny | skóre: 2
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Odpovědět | Sbalit | Link | Blokovat | Admin
PS1="\h@\u \w \$ " # bude vypadat takto: dave@amd64 /tmp $

je prohozené \h a \u.
David Watzke avatar 17.3.2010 00:18 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Pravda, díky.
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
17.3.2010 08:02 Robert Krátký | skóre: 94 | blog: Robertův bloček
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Opraveno.
17.3.2010 01:03 Jan Grmela | skóre: 45 | blog: Kilo šťávy z lachtana | Brno
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Odpovědět | Sbalit | Link | Blokovat | Admin
Pěkné, díky. Bez různě obarveného shellu na různých strojích bych asi už způsobil hodně škody. Člověk si otevře několik terminálů, na každém jiný počítač, pak na to zapomene, někde mu vytimeoutuje sešna...nebo taky ne a aktualizované jádro na serveru místo na desktopu je na světě. Od té doby, co si důsledně obarvuji prompty různými barvami, tak se mi tyto nešťastně zadané příkazy mnohem víc vyhýbají.
brk avatar 21.3.2010 07:44 brk | skóre: 29 | blog: broukoviny
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
A taky při vypínání lokálního počítače se snažím sahat raději po myši, pokud cíleně nechci vypnout vzdálený server.
USE="-qt -kde"
17.3.2010 06:21 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Odpovědět | Sbalit | Link | Blokovat | Admin
Příloha:
PROMPT_COMMAND je zbytečnost (viz obrázek)...
In Ada the typical infinite loop would normally be terminated by detonation.
17.3.2010 08:01 Robert Krátký | skóre: 94 | blog: Robertův bloček
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Smajlíky jsou pěkné řešení :-)
17.3.2010 12:31 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Také používám na odlišení strojů různé barvy / styly promptu. Místo hostname pak mám nějaký symbolický obrázek.
In Ada the typical infinite loop would normally be terminated by detonation.
17.3.2010 12:45 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Ale to ti pre kazdy prompt spusta novy proces, co pri zatazenom stroji nejaku chvilu trva. Nemam to z vlastnej hlavy, ale od niekoho napaditejsieho na tomto serveri, ktoreho teraz nejak neviem vyhladat:
\[\033[01;31m\]${?/#0/}\[\033[01;36m\]
Hlavny trik je ${?/#0/}, ktory zabezpeci vypis/nevypis podla navratovej hodnoty aj bez spustenia procesu.
If you hold a Unix shell up to your ear, you can you hear the C.
17.3.2010 20:20 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Abyste se nedivil...
$ echo $$ `if [[ 0 -eq 0 ]] ; then echo $$; fi`
10184 10184
In Ada the typical infinite loop would normally be terminated by detonation.
David Watzke avatar 17.3.2010 20:34 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
$ echo $$ `ll /proc/self`
7651 lrwxrwxrwx 1 root root 64 2010-03-17 20:15 /proc/self -> 4123/
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
David Watzke avatar 17.3.2010 20:36 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Hmm.. aha, to jsem napsal blbost :-D Ignorovat, prosím.
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
17.3.2010 20:48 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
problém je že tím ll spustíte program ls, zatímco v tom mém případě jde vše přes builtiny bashe. a zdá se, že bash je dost línej na to, aby pouštěl kvůli sám sobě novej proces.
In Ada the typical infinite loop would normally be terminated by detonation.
18.3.2010 14:04 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Zaujimave. Vzhladom na rovnake vysledky pre vsetky 3 pripady:
echo $$
echo `echo $$`
echo `ls; echo $$`
To vyzera, ze ani nerozlisuje, ci treba pustat novy proces alebo si vystaci sam, ale skutocne to vykonava v kontexte jedneho procesu
If you hold a Unix shell up to your ear, you can you hear the C.
18.3.2010 14:16 cronin | skóre: 49
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
V akom poradi sa to expanduje? Cosi sa mi mari ze $$ sa dedi aj do subshellov.
Fill avatar 18.3.2010 14:41 Fill | skóre: 19 | blog: Fill | Třebíč
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Echo je builtin, ls nový proces, po jeho skončení jste zpět v původním shellu:
$ echo -e "$$ \n`ls -l /proc/self; echo $$`"
5287 
lrwxrwxrwx 1 root root 64 2010-03-18 08:57 /proc/self -> 10210
5287
18.3.2010 18:40 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Ha, pravda. Naspat na stromy. $$ nie je prave spolahlive.
$$ Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the current shell, not the subshell.
Ked som skusil nieco ako grep napisane v cistom bashi, tak sa pid meni:
$ echo $$
6096
$ echo `while read l; do [[ "$l" == Pid:* ]] && echo "$l"; done </proc/self/status`
Pid: 7667
$ echo `while read l; do [[ "$l" == Pid:* ]] && echo "$l"; done </proc/self/status`
Pid: 7668
Trocha to vidno na premennej BASH_SUBSHELL
$ echo $BASH_SUBSHELL
0
$ echo `$ echo $BASH_SUBSHELL`
1
If you hold a Unix shell up to your ear, you can you hear the C.
19.3.2010 09:39 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
To je pravda, to mě nenapadlo. Ale:
echo $$ `echo \$\$`
18053 18053

echo $$; (eval echo '$$')
18053
18053

echo $$ ` (eval echo '\$\$') `
18053 18053
Pokud chcete definitivní odpověď, zkuste strace :-)
In Ada the typical infinite loop would normally be terminated by detonation.
19.3.2010 13:31 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Podla mna nie je problem s prilis skorou expanziou $$ (comu asi malo predchadzat \$\$). Ale, ze vdaka:
it expands to the process ID of the current shell, not the subshell.
aj pozdna expanzia vracia pid nadradeneho shellu. Nesfalsovanu hodnotu som ziskal z /proc/self/status.

Ked som sa externym strace pripojil na bash a spustil echo `echo \$\$`, tak vo vypise syscallov je pipe a hned za nim clone. Takze proces sa vytvara.
If you hold a Unix shell up to your ear, you can you hear the C.
Milan Vít avatar 17.3.2010 09:14 Milan Vít | skóre: 23 | blog: about:linux | Orlová
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Odpovědět | Sbalit | Link | Blokovat | Admin

Já kdysi používal něco takového, ale když se na to dívám zpětně, asi bych už takovou šílenost nikdy znovu nechtěl :-)

„There is no dark side of the Moon really… as a matter of fact it's all dark.“
17.3.2010 09:30 cynan | skóre: 3
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
:-))))), tak tos byl fakt vostrej; kdyz jsem zacinal s linuxem, tak bych si to tam asi taky dal...
nejlepsi je Ferda
lmanik avatar 17.3.2010 13:05 lmanik | skóre: 11 | Vracov
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku

:-D jo tak tuhle zrudu jsem pouzival taky

A komu to cpes?
Marek Bernát avatar 18.3.2010 12:04 Marek Bernát | skóre: 17 | blog: Arcadia
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku

Hehe, tak to je nás viac (resp. bolo) :-)

physics.stackexchange.com -- Q&A stránky o fyzike v štýle StackOverflow.
17.3.2010 17:42 hlupy
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Odpovědět | Sbalit | Link | Blokovat | Admin

Ja to mam takto a staci mi :

[ martin@~/workspace/ ]:16:25:^_^:

> qwert

bash: qwert: command not found

[ martin@~/workspace/ ]:16:39:-_-:

>

Limoto avatar 17.3.2010 21:41 Limoto | skóre: 32 | blog: Limotův blog
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Odpovědět | Sbalit | Link | Blokovat | Admin
Já spokojeně používám Wolfman's.
Nicky726 avatar 17.3.2010 23:54 Nicky726 | skóre: 56 | blog: Nicky726
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
+1 akorát začínám uvažovat o těch různejch barvičkách na různech strojích, už jsem se párkrát divil při aktualizacích...
Enjoy the detours. There you’ll find the things more important than what you want. (Hunter x Hunter)
Josef Kufner avatar 17.3.2010 21:44 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Odpovědět | Sbalit | Link | Blokovat | Admin
A jak vám to funguje v mc?
Hello world ! Segmentation fault (core dumped)
David Watzke avatar 17.3.2010 22:37 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
$ mc
bash: mc: command not found
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
18.3.2010 01:30 Jan Grmela | skóre: 45 | blog: Kilo šťávy z lachtana | Brno
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
+1

Nějak jsem si nikdy na mc nezvykl :-)
Limoto avatar 18.3.2010 15:59 Limoto | skóre: 32 | blog: Limotův blog
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
+1
Josef Kufner avatar 19.3.2010 18:25 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Máš to rozbitý :-D
Hello world ! Segmentation fault (core dumped)
24.3.2010 21:16 Marble | skóre: 27 | blog: marble
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
mc si zapamatuje promtový string při svém spuštění a ten používá. Tedy "backslashové" expanze fungují stejně, barvičky a jiné terminálovosti také. Ale pokud je promt generovaný pomocí $PROMPT_COMMAND, tak tahle funkce se už nevolá a celou dobu se používá prompt vygenerovaný v okamžiku spuštění mc.
18.3.2010 10:01 Adeilon
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Odpovědět | Sbalit | Link | Blokovat | Admin
Muj Bash neni omalovanka!
18.3.2010 15:14 petznaku | skóre: 11 | blog: lo0makovo_stesky
Rozbalit Rozbalit vše Re: Bash prompt: Vzhled a obsah příkazového řádku
Odpovědět | Sbalit | Link | Blokovat | Admin
nejedu v bashi, ale zsh a používám lehce upravený geniální prompt od Aarona Toponce.. spousta informací na jednom místě a přitom parádně přehledné... článek + ss zde
22.3.2010 15:27 Harvie
Rozbalit Rozbalit vše Vizualizace návratové hodnoty...
Odpovědět | Sbalit | Link | Blokovat | Admin
http://wiki.archlinux.org/index.php/Color_Bash_Prompt#Advanced_return_value_visualisation

můžete si vybrat číslo, nebo barevného smajlíka - já používám oboje ;-) myslím totiž, že je hlopé, pokud je výstup příkazů true a false (a nejen tech) naprosto identický...
22.3.2010 23:41 Ash | skóre: 53
Rozbalit Rozbalit vše Re: Vizualizace návratové hodnoty...
Reakce promptu na true a false není identická v žádné z možností "jen číslo" "jen smajlík" "číslo i smajlík", takže jak jste to myslel?

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.