Prosíme přihlašte se nebo zaregistrujte.

Přihlašte se svým uživatelským jménem a heslem.

Autor Téma: Jak v terminálu obarvit příkazy namísto výzvy  (Přečteno 945 krát)

singularis

  • Člen
  • **
  • Příspěvků: 143
    • Zobrazit profil
Jak v terminálu obarvit příkazy namísto výzvy
« kdy: 03 Leden 2021, 07:35:58 »
Připadne mi mnohem praktičtější mít namísto prvků výzvy v terminálu obarvené příkazy, které jsem zadal/a. Následujícím trikem toho lze docílit:

Kód: [Vybrat]
PS0=$(tput sgr0)
PS1="\\[$(tput sgr0)\\]\\u@\\h:\\w\\$ \\[$(tput setaf 2; tput bold)\\]"
PS2="\\[$(tput sgr0)\\]> \\[$(tput setaf 2; tput bold)\\]"

Případně pokud chcete jen obarvit příkazy bez změny stávající výzvy:

Kód: [Vybrat]
PS0=$(tput sgr0)
PS1="\\[$(tput sgr0)\\]${PS1}\\[$(tput setaf 2; tput bold)\\]"
PS2="\\[$(tput sgr0)\\]${PS2}\\[$(tput setaf 2; tput bold)\\]"

Řešení je založené na výzvě $PS0, kterou bash vypisuje před spuštěním zadaného příkazu, a tedy je možné ji využít ke zrušení barvení.

GdH

  • Moderátor
  • Závislák
  • ***
  • Příspěvků: 3126
    • Zobrazit profil
    • GdH-Notes
Re:Jak v terminálu obarvit příkazy namísto výzvy
« Odpověď #1 kdy: 04 Leden 2021, 23:00:26 »
Obarvení a ztučnění toho, co píšu je vlastně docela dobrý nápad  :) Tak mě napadlo do promptu cvičně zakomponovat měření času od spuštění příkazu do zobrazení PS1, občas ladím efektivitu skriptu..
Kód: [Vybrat]
PS0='\[\033[m\]$(echo $(date +"%s%3N") > /dev/shm/promptt)'
PS2='\[\033[m\]>\[\033[1;92m\] '
PS1='\[\033[m\]$( [[ "$?" -ne 0 ]] && echo "\[\033[91m\]")$(($(date +"%s%3N")-$(cat /dev/shm/promptt))) ms^ \[\033[m\]\u@\h:\w\n\$ \[\033[1;92m\]'

Čas spuštění příkazu v milisekundách ukládám z PS0 do souboru /dev/shm/promptt v RAM a pak ho odečtu při zobrazení nového promptu v PS1. Přidal jsem i barevnou indikaci nenulového exit kódu. Místo tput používám pro definice stylu a barev rovnou ANSI escape sekvence, které padají z tput také (i když ne všechny, které umí terminál).

singularis

  • Člen
  • **
  • Příspěvků: 143
    • Zobrazit profil
Re:Jak v terminálu obarvit příkazy namísto výzvy
« Odpověď #2 kdy: 05 Leden 2021, 05:25:36 »
Měření času tímto způsobem je vynikající nápad. Děkuji za tip! Určitě ho použiji.

Jen ten soubor bych uložil/a do /tmp (které mám na ramdisku) a do jeho názvu bych zakomponoval/a PID ($$), aby se to nepletlo v případě, kdy jsou spuštěné příkazy ve více instancích bashe. Také je potřeba vyřešit mazání pro případ, kdy je přihlášených víc uživatelů a jeden bash zavře a druhý otevře nový bash, který náhodou dostane stejné PID, ale to už nějak vymyslím...

ANSI sekvence jsou samozřejmě také použitelné, ale hůř se čtou a pamatují. „tput bold“ si snadno zapamatuje kdokoliv, kdo zná alespoň náznak angličtiny, zatímco „\e[1m“ se většině lidí pamatuje mnohem hůř.

A když už ty ANSI sekvence v proměnné jsou, dají se čitelně vypsat takto:
Kód: [Vybrat]
sed -E $'s/\e/\\e/g' <<< "$PS1"

GdH

  • Moderátor
  • Závislák
  • ***
  • Příspěvků: 3126
    • Zobrazit profil
    • GdH-Notes
Re:Jak v terminálu obarvit příkazy namísto výzvy
« Odpověď #3 kdy: 05 Leden 2021, 10:40:21 »
K ošetření tu pár věcí rozhodně je, na druhou stranu zas prompt nechci zdržovat nějakou velkou režií a viděl bych to u mě spíš na dočasné, než trvalé použití. Ty escape sekvence jsou sice komplikovanější na zápis, ale když si hraju s parametry, je změna čísla rychlejší, navíc nemusím řešit expanzi.

singularis

  • Člen
  • **
  • Příspěvků: 143
    • Zobrazit profil
Re:Jak v terminálu obarvit příkazy namísto výzvy
« Odpověď #4 kdy: 21 Leden 2021, 15:50:15 »
Podařilo se mi to měření času ještě vylepšit:
Kód: [Vybrat]
PROMPT_TIMESTAMP=$(date +%s%1N)
trap 'PROMPT_TIMESTAMP=$(date +%s%1N)' SIGUSR2
PS0="${PS0}\$(kill -SIGUSR2 $$)"
PS1='$((($(date +%s%1N) - PROMPT_TIMESTAMP + 5) / 10))s) '"$PS1"

Toto řešení:
  • nevytváří dočasné soubory
  • má nízkou režii (volá jen tři externí procesy na zadaný příkaz)
  • zaokrouhluje naměřený čas na celé sekundy
Uvedený kód patří do „.bashrc“ (pro perzistentní použití) nebo zadat přímo to terminálu (pro dočasné použití).

GdH

  • Moderátor
  • Závislák
  • ***
  • Příspěvků: 3126
    • Zobrazit profil
    • GdH-Notes
Re:Jak v terminálu obarvit příkazy namísto výzvy
« Odpověď #5 kdy: 21 Leden 2021, 16:29:43 »
Podařilo se mi to měření času ještě vylepšit:
Kód: [Vybrat]
PROMPT_TIMESTAMP=$(date +%s%1N)
trap 'PROMPT_TIMESTAMP=$(date +%s%1N)' SIGUSR2
PS0="${PS0}\$(kill -SIGUSR2 $$)"
PS1='$((($(date +%s%1N) - PROMPT_TIMESTAMP + 5) / 10))s) '"$PS1"

Toto řešení:
  • nevytváří dočasné soubory
  • má nízkou režii (volá jen tři externí procesy na zadaný příkaz)
  • zaokrouhluje naměřený čas na celé sekundy
Uvedený kód patří do „.bashrc“ (pro perzistentní použití) nebo zadat přímo to terminálu (pro dočasné použití).

Tohle je moc pěkné, to mě nenapadlo, rozhodně je tam menší prodleva a hlavně konzistentní. Jen ty sekundy by mi nestačily, díky tomu mému promptu jsem si v poslední době uvědomil pár drobností, například to, že pgrep je skoro řádově pomalejší, než ps filtrovaný přes dvě roury, a to proto, že jsem v promptu viděl 150 ms vs 20 ms :)

singularis

  • Člen
  • **
  • Příspěvků: 143
    • Zobrazit profil
Re:Jak v terminálu obarvit příkazy namísto výzvy
« Odpověď #6 kdy: 21 Leden 2021, 17:09:35 »
Jen ty sekundy by mi nestačily
Předělat to na milisekundy je poměrně triviální :) :
Kód: [Vybrat]
PROMPT_TIMESTAMP=$(date +%s%4N)
trap 'PROMPT_TIMESTAMP=$(date +%s%4N)' SIGUSR2
PS0="${PS0}\$(kill -SIGUSR2 $$)"
PS1='($((($(date +%s%4N) - PROMPT_TIMESTAMP + 5) / 10))ms) '"$PS1"

GdH

  • Moderátor
  • Závislák
  • ***
  • Příspěvků: 3126
    • Zobrazit profil
    • GdH-Notes
Re:Jak v terminálu obarvit příkazy namísto výzvy
« Odpověď #7 kdy: 21 Leden 2021, 17:30:43 »
Jen ty sekundy by mi nestačily
Předělat to na milisekundy je poměrně triviální :) :

Trivilání to je, ale zaokrouhlovat ms už je trochu moc i na mě ;D
Každopádně díky za ten trap, už jsem to implementoval.
« Poslední změna: 21 Leden 2021, 17:33:19 od GdH »