Ich drucke eine Nachricht in einem Bash-Skript und möchte einen Teil davon einfärben. zum Beispiel,
#!/bin/bash
normal='\e[0m'
yellow='\e[33m'
cat <<- EOF
${yellow}Warning:${normal} This script repo is currently located in:
[ more messages... ]
EOF
Aber wenn ich im Terminal ( tmux
innen gnome-terminal
) laufe, werden die ANSI-Escape-Zeichen nur in \
Form gedruckt . zum Beispiel,
\e[33mWarning\e[0m This scr....
Wenn ich den Teil, den ich einfärben möchte, in einen printf
Befehl außerhalb des Here-Dokuments verschiebe, funktioniert dies. Zum Beispiel funktioniert dies:
printf "${yellow}Warning:${normal}"
cat <<- EOF
This script repo is currently located in:
[ more messages... ]
EOF
Von man bash
- Hier Dokumente:
Für Word werden keine Parameter- und Variablenerweiterungen, Befehlssubstitutionen, arithmetischen Erweiterungen oder Pfadnamenerweiterungen ausgeführt . Wenn Zeichen in Wörtern in Anführungszeichen gesetzt werden, ist das Trennzeichen das Ergebnis der Entfernung von Anführungszeichen in Word , und die Zeilen im Dokument hier werden nicht erweitert. Wenn das Wort nicht in Anführungszeichen gesetzt ist, werden alle Zeilen des hier beschriebenen Dokuments einer Parametererweiterung, einer Befehlssubstitution und einer arithmetischen Erweiterung unterzogen. Im letzteren Fall wird die Zeichenfolge \ <newline> wird ignoriert und
\
muss verwendet werden , um die Zeichen zu zitieren\
,$
und`
.
Ich kann nicht herausfinden, wie sich dies auf ANSI-Escape-Codes auswirken würde. Ist es möglich, ANSI-Escape-Codes in einem cat
ausgeblendeten Bash-Here-Dokument zu verwenden?
quelle
\e[33m
und wird in beiden Fällen normal ersetzt. Wenn Sie Grund zu der Annahme haben, dass es sich um Heredocs handelt, oder um einen echten Code, der das Verhalten zeigt, an dem Sie interessiert sind, bearbeiten Sie ihn bitte in.yellow=$'\e[33m'
oderyellow=$(printf '\e[33m')
(wie Sie es bereits tun) setzt das Escape-Zeichen direkt in die Zeichenfolge, um es zu testen.'\e[33m'
für ein Terminal bedeutungslos? es hat nur Bedeutung für Befehle wieecho -e
oderprintf
- die dann den "echten" Code erzeugen, der an das Terminal gesendet wird?Antworten:
In Ihrem Skript diese Zuordnungen
Setzen Sie diese Zeichen buchstäblich in die Variablen ein, dh \e[0mnicht in die Escape-Sequenz. Sie können ein Escape-Zeichen mit
printf
(oder einigen Versionen vonecho
) erstellen , z.Sie sollten es jedoch viel besser verwenden
tput
, da dies für jedes korrekt eingerichtete Terminal funktioniert:Wenn Sie sich Ihr Beispiel ansehen, scheint es, dass die Version von
printf
Ihnen Leckereien\e
als Escape-Zeichen verwendet (was auf Ihrem System möglicherweise funktioniert, aber im Allgemeinen nicht auf andere Systeme portierbar ist). Versuchen Sie es, um dies zu sehenund Sie würden die wörtlichen Zeichen sehen:
eher als die Escape-Sequenz. Wenn Sie diese in das
printf
Format einfügenprintf
, werden sie interpretiert (wenn dies möglich ist).Weiterführende Literatur:
quelle
yellow
funktionierte nicht, aber dasnormal
tat es). aber dasnormal=$(tput sgr0)
format funktioniert einwandfrei!printf 'Yellow:%s\n' $yellow
produzierte wörtliche Zeichen, weilprintf
es keineYellow
"spezielle" Behandlung gab. Der Grund dafürprintf "%s" "$(tput setaf 3)foo$(tput sgr0)"
ist, dass tput Escape-Sequenzen generiert, die das Terminal direkt erkennen kann. Gut zu wissen, danke!red=$'\e[31m'
in ksh93, bash, zsh, mksh, FreeBSD sh und bald POSIX.Bei diesen Zuweisungen werden keine maskierten Zeichen in die Variable eingefügt:
Dazu benötigen Sie
echo -e
printf
oder$'...'
(in Bash).Da Sie bash verwenden, können Sie auch Folgendes verwenden:
Bitte beachten Sie die
$
vor der Zeichenfolge'\e[0m'
.Der tragbare Weg, um maskierte Zeichen zu erhalten, ist jedoch printf, wie folgt:
Der Oktalwert (033) des Escapezeichens ist in allen POSIX-Shells gültig.
quelle
$'\e[0m
in der nächsten Haupt Ausgabe der POSIX - Spezifikation sein und wird bereits unterstützt inksh93
(wo es herkommt)bash
,zsh
,mksh
und FreeBSDsh
zumindest.echo -e
Ausgabe"-e\n"
in POSIX-kompatiblen Echo-Implementierungen erfolgt.echo '\033'
gibt ein ESC-Zeichen mit Unix-konformenecho
s auf ASCII-basierten Systemen aus.printf
eine gute Lösung ist. Und dass die Verwendung von printf eine Möglichkeit war, die Präsentation, Diskussion und endgültige Ablehnung der Verwendung desecho
Befehls " Fehlerhaftes in mehrfacher Hinsicht" zu vermeiden . Was macht es nützlich,echo
in dieser Antwort auf den Befehl zu verweisen ?