Wie drucke ich '-e' mit Echo?

8

Ich weiß, dass echo -edas kein gewöhnlicher Befehl ist. Ich habe es versucht echo '-e'und echo \-eaber sie funktionieren immer noch nicht.

Highlights Fabrik
quelle
1
Was meinst du mit "keine gewöhnliche Kommandozeile"? echoist in der Regel eine Shell eingebaut, aber es gibt in der Regel auch /usr/bin/echo. Das -eist nicht POSIX, aber zB mit Bash erhältlich. Bitte geben Sie mehr Details an, was Sie mit "sie funktionieren immer noch nicht" meinen. Was ist das erwartete Verhalten?
Maxschlepzig
Ich möchte -e mit Echo drucken. Irgendwelche Vorschläge?
Höhepunkte Fabrik
3
Erwägen Sie die Verwendung von printf, es ist portabler.
Michael Durrant
1
Seltsamerweise echo -- -efunktioniert es auch nicht. Herkömmlicherweise (zumindest bei GNU-Dienstprogrammen) gibt der doppelte Bindestrich das Ende der Optionen an, während der Rest als wörtliche Argumente beibehalten wird.
Wil Cooley
6
echowieder Wahnsinn. Wenn die Leute nur benutzen würden printfund niemals zurückblicken würden.
Jens

Antworten:

9
  • mit newline

    echo -en '-e\n'
  • ohne Zeilenumbruch

    echo -e '-e\c'
  • mit Leerzeichen um:

    echo '-e '
    echo ' -e'
  • mit Rücktaste (danke an Joseph R.):

    echo -e ' \b-e'

    (SPC BS - e LF wird ausgegeben, aber wenn es an ein Terminal gesendet wird, das so gerendert wird, -ewie BS, bewegt der Cursor eine Spalte nach links zurück, wodurch -die SPC überschrieben wird.)

Das Verhalten von bash's echoeingebaut kann von der Bash-Version abhängen. Es hängt auch von der Umwelt ( POSIXLY_CORRECT, SHELLOPTSund BASHOPTSVariablen), die Optionen ( posix, xpg_echo), die Build - Optionen und argv[0]( shvs bash). Hier getestet mit GNU bash 4.2.53(1), Standard-Build, Standardoptionen, leere Umgebung, aufgerufen als bash. Funktioniert auch mit zsh 5.0.5.

jimmij
quelle
+1 Auchecho -e 'x\b-e'
Joseph R.
2
Warum erhalten diese bis auf die Knochen verschleierten "Workarounds" positive Stimmen? Charles Duffy unten hat die richtige Antwort: Verwenden Sie printf und vergessen Sie solche Probleme ein für alle Mal.
Jens
7
Jens: weil das OP gefragt hat, wie es mit dem echoBefehl gemacht werden soll. Haltung nicht notwendig.
CTC
1
echo -e ' \b-e'gibt space-backspace-dash-e aus. Nur in einem Terminal angezeigt, gibt es Ihnen die Illusion, dass es Dash-E ist.
Stéphane Chazelas
1
@CharlesDuffy, echo -e "\0-e"gibt aus NUL-dash-e. Es ist nur so , dass die Klemmen ignorieren , dass NUL - Zeichen (NULs sogar an einige Terminals gesendet verwendet werden (die nicht Flusskontrolle unterstützt haben) ihnen Zeit zu geben , andere lange Dinge wie ein Wagenrücklauf zu tun. Siehe Abschnitt unter Verzögerungen und Padding in terminfo(5).)
Stéphane Chazelas
25

Die beste Lösung ist nicht zu verwenden echo, sondern zu verwenden printf.

printf '%s\n' -e

Dies funktioniert mit beliebigen Variablen:

var=-e
printf '%s\n' "$var"

... was bedeutet, dass Sie an keiner anderen Stelle in Ihrem Code spezielle Vorbereitungen / Änderungen vornehmen müssen, basierend auf dem Wissen, dass ein Wert echod sein wird.


Im Übrigen bestätigt die POSIX-Shell-Befehlsspezifikation fürecho , dass sie als implementiert nicht portierbar ist, und enthält einen Hinweis zu diesem Thema:

Es ist nicht möglich, Echo auf allen POSIX-Systemen portabel zu verwenden, es sei denn, sowohl -n (als erstes Argument) als auch Escape-Sequenzen werden weggelassen.

Das Dienstprogramm printf kann portabel verwendet werden, um eines der traditionellen Verhaltensweisen des Dienstprogramms echo wie folgt zu emulieren (vorausgesetzt, IFS hat seinen Standardwert oder ist nicht festgelegt):

Das historische System V-Echo und die Anforderungen an XSI-Implementierungen in diesem Band von POSIX.1-2008 entsprechen:

printf "%b\n" "$*"

Das BSD-Echo entspricht:

if [ "X$1" = "X-n" ]
then
    shift
    printf "%s" "$*"
else
    printf "%s\n" "$*"
fi

Neue Anwendungen sollten printf anstelle von echo verwenden.

(Betonung hinzugefügt).


Auf GNU-Systemen gibt es jedoch eine Alternative: Anfordern von standardkonformem Verhalten.

$ POSIXLY_CORRECT=1 /bin/echo -e
-e
Charles Duffy
quelle
Interessanterweise besagt der POSIX-Hinweis, dass er echo -eportabel ist. Es heißt, -nmuss vermieden werden, und Escape-Sequenzen müssen vermieden werden. echo -evermeidet beides. Wie Sie im letzten Teil Ihrer Antwort angegeben haben, müssen Sie sich auf GNU-Systemen echostandardmäßig überhaupt nicht an POSIX anpassen, und POSIX stellt nur die Portabilität zwischen POSIX-Systemen fest.
DVD
@hvd, ich sehe nicht -ein dem Teil der Spezifikation, mit dem ich verlinkt habe. Könnten Sie einen Link oder ein Zitat bereitstellen, das dies abdeckt?
Charles Duffy
Es ist das Fehlen einer Erwähnung, die es sagt. :) Es werden die Verwendungen aufgelistet, die nicht portabel sind und -enicht erwähnt werden, ebenso -ewie portabel (wiederum über POSIX-Systeme hinweg). Um fair zu sein, ist das, was Sie zitiert haben, informativ, aber der normative Text sagt dasselbe: "Wenn der erste Operand -n ist oder wenn einer der Operanden ein <backslash> -Zeichen enthält, sind die Ergebnisse implementierungsdefiniert."
hvd
2
@hvd, eher das Gegenteil. Um die angegebene Leistung zu erbringen, echomüssen alle Argumente ausgegeben werden, deren Verhalten vom Standard nicht anders definiert ist. So - im Gegensatz zu fast allen anderen Befehlszeilen von der POSIX - Spezifikation abgedeckt Tool - echotatsächlich gibt an Verhalten für Argumente nicht gegeben: sie zu drucken. Es gibt keinen Platz zum Hinzufügen neuer Flags, ohne die Spezifikation zu brechen.
Charles Duffy
2
@hvd, ... siehe dazu den OPTIONSAbschnitt, in dem es in Schwarzweiß dargestellt ist : Implementations shall not support any options.
Charles Duffy
9

Mit GNU echo‚s -emit dem ASCII - Codes für die Zeichen:

$ /bin/echo -e '\055'e
-e

055ist die oktale ASCII-Nummer für -(siehe man asciiKurzanleitung).

muru
quelle
1
/bin/echoist in der Tat POSIX-spezifiziert. Die Interpretation von oktalen Escape-Sequenzen ist jedoch eine XSI-Erweiterung der Basisspezifikation.
Charles Duffy
@ CharlesDuffy In der Tat habe ich falsch geschrieben. +1 für printf (auch mein erster Gedanke). Gibt es angesichts der Tatsache, dass -ees sich um eine Erweiterung handelt, eine Möglichkeit, das reine POSIX-Verhalten zu erzwingen echo? Das würde jede Unsicherheit darüber beseitigen, denke ich.
15.
2
Eigentlich ja! Das Exportieren POSIXLY_CORRECT=1führt zu einem POSIX-kompatiblen Verhalten für GNUs /bin/echo.
Charles Duffy
+1 Danke, gut zu wissen, dass Sie Ihre Skripte portabel und "Homebrew-Linux-unabhängig" halten (dh auch auf einer Pro-Workstation bei der Arbeit arbeiten).
Syntaxfehler
@Kusalananda hat das vergessen.
Muru
3

Während die offensichtliche, standardmäßige und empfohlene Lösung zu verwenden ist printf, echokann es je nach Implementierung ziemlich schwierig sein , dies zu tun (nicht so schwierig wie zuvor -n).

POSIX.2017-konform echos

POSIX muss echo -e ausgegeben werden -e<newline>. Also ist es einfach

echo -e

Dort. POSIX-konforme echos in dieser Hinsicht (die meisten von ihnen sind in anderer Hinsicht nicht POSIX-konform, die POSIX-Spezifikation ist nahezu nutzlos, wenn es darum geht echo) umfassen:

  • die echobuiltin der , bashwenn sowohl die xpg_echound posixOptionen haben (zur Laufzeit oder Build - Zeit wie für die aktiviert wurde /bin/shvon Apple MacOS). set -o posix; shopt -s xpg_echo(Die posixOption kann auch aktiviert werden, wenn sie als shoder wann POSIXLY_CORRECToder SHELLOPTS=posixin der Umgebung aufgerufen wird.)
  • die /bin/echovon zertifizierten UNIX-Systemen (mindestens AIX, macOS, Solaris) und den meisten BSDs
  • das echoeingebaute von dash, ksh88die Bourne-Muschel, csh, tcsh, posh, rc, es, akanga
  • GNU echo( /bin/echoauf GNU-Systemen), wenn POSIXLY_CORRECTes sich in der Umgebung befindet.
  • Das echoeingebaute mkshund einige andere pdksh- Ableitungen, wenn ihre posixOption aktiviert ist.
  • die echoeingebaute der , yashwenn $ECHO_STYLEentweder nicht gesetzt oder eines von SYSV, XSI, BSD, DASH,RAW

Implementierungen, die unterstützen -e

Inklusive echoder Forschung Unix V8 (wo es herkommt), GNU, Busybox, die echobuiltin von bash, zsh, pdkshund Derivate, fisheinige ash-basierte Shells wie busybox shoder die shvon einigen BSDs, neueren Versionen von ksh93(auf einigen Systemen und mit einigen Werten von $PATH) mit ihren Standardeinstellungen, yashmit $ECHO_STYLEeiner von GNUoder ZSH:

echo -e '-e\n\c'

Die Implementierungen, die -eausnahmslos unterstützen -n, unterstützen also:

echo -ne '-e\n'

würde auch funktionieren.

zsh

zsh's echoist die einzige mir bekannte Implementierung, die einen End-of-Option-Marker ( -) unterstützt.

echo - -e

Damit ist es die einzige Bourne-ähnliche Shell echo, die beliebige Daten ausgeben kann (auch weil es die einzige ist, die NUL-Bytes in ihren Variablen und den Argumenten ihrer integrierten Funktionen unterstützt echo -E - "$data").

Mit Ausnahme des NUL-Byte-Problems sind andere Implementierungen, die beliebige Daten ausgeben können, FreeBSD oder macOS, /bin/echowo Sie Folgendes tun können:

/bin/echo "$data
\c"

(wird in dieser Implementierung \cerst am Ende erkannt und es wird keine andere Escape-Sequenz unterstützt).

Und yash's:

ECHO_STYLE=RAW echo "$data"

(Beachten Sie jedoch, dass yashVariablen nur Text enthalten können, also keine beliebigen Bytesequenzen in Gebietsschemas, in denen nicht alle Bytesequenzen gültige Zeichen bilden können, wie bei UTF-8 als Charmap).

Stéphane Chazelas
quelle
2

Verwenden Sie -n, um Zeilenumbrüche zu vermeiden:

$ echo -n - && echo e
-e
vishalknishad
quelle
Das funktioniert nicht dort, zshwo -das Ende des Optionsbegrenzers liegt oder bei allen echoImplementierungen, die nicht unterstützt werden -n(diejenigen, die dies -eebenfalls unterstützen -n)
Stéphane Chazelas,