Kann ein Linux-Befehl Großbuchstaben enthalten?

17

Kann ein Linux-Befehl Großbuchstaben enthalten? Ich weiß, dass es unterstützt wird, aber ich möchte sicher sein, ob es ein "Problem" ist oder "keine gute Sache" ist?

terdon
quelle
6
Die UNIX-Konvention sieht die Verwendung von Kleinbuchstaben für Befehlsnamen vor, Sie können sie jedoch nach Belieben aufrufen.
1
In der Tat ist es UNIX egal, wie Sie Ihre Befehle aufrufen. Es wird viel Schmerz und Leid verursachen, aber Sie können sogar Befehle mit Leerzeichen haben: echo -e '#!/bin/sh\necho hello world' > ~/bin/OH\ NOES; chmod +x ~/bin/OH\ NOES; "OH NOES"Produziert hello worldwie erwartet. (Vorausgesetzt, es ~/binliegt in Ihrem $PATH).
Derobert
Schauen Sie sich diese Frage und mein vielleicht zu langes Tutorial an .
Emanuel Berg

Antworten:

13

Es gibt keine Einschränkung für Befehlsnamen unter Unix. Jede Datei kann ein Befehl sein. Und ein Dateiname kann eine beliebige Folge von einem oder mehreren (bis zu einer gewissen Grenze) anderen Zeichen als ASCII NUL oder ASCII sein /. zshhebt diese Einschränkung sogar für Funktionen auf, bei denen Sie eine beliebige Zeichenfolge als Funktionsnamen verwenden können.

Ein paar Anmerkungen:

  • Es fällt Ihnen schwer, eine Befehlsdatei mit dem Namen .oder zu erstellen ..;-).
  • Vermeiden Sie Namen , die durch Standardbefehle oder Shell builtins oder Keywords bereits getroffen werden (zumindest der am häufigsten verwendeten Shells wie bash, zsh, tcshoder ksh). In dieser Hinsicht können Großbuchstaben hilfreich sein, da sie in der Regel nicht von Standardbefehlen verwendet werden.
  • Es ist besser, auf ASCII-Zeichen zu beschränken. Nicht-ASCII-Zeichen werden in den verschiedenen Zeichensätzen nicht gleich ausgedrückt
  • Beschränken Sie sich dabei auf Buchstaben, Ziffern, Bindestriche, Punkte und Unterstriche. Alles andere, während Rechts, kann ein Problem oder eine andere mit diesem oder jenem Werkzeug (zum Beispiel |, =, &und viele andere müssten in Schalen entkommen werden, wenn Sie verwenden :, kann Ihr Befehl nicht als einer der Login - Shell verwendet werden ... ). Sie können sogar ausschließen wollen .und -die nicht in Funktionsnamen in vielen Schalen erlaubt, falls Sie es Benutzern ermöglichen möchten Ihren Befehl in einer Shell - Funktion zu wickeln.
  • Machen Sie aus dem ersten Buchstaben einen Buchstaben. Wieder keine strenge Anforderung. Aber manchmal wird ein Unterstrich für spezielle Dinge verwendet (wie in zshden Funktionen, mit denen die Vervollständigungssysteme beginnen _), und all-stellige Befehle können in Dingen wie ein Problem sein cmd>output.log. Dateien, deren Name mit einem Punkt beginnt, werden von lsObjekten wie oder Shell-Globbings und vielen Dateimanagern ausgeblendet .
Stéphane Chazelas
quelle
Richtig. Ich denke, es läuft darauf hinaus, nichts Außergewöhnliches zu verwenden, es sei denn, Sie haben einen guten Grund, dies zu tun. Selbst Ihr zweiter Punkt, ich denke nicht, dass die Verwendung von Großbuchstaben zum Abdecken dieser Shells so klug ist - ist es nicht besser, den Befehl zu benennen, um die Änderung zu beschreiben? Wie zsh_with_some_funky_option(anstelle von ZSH)?
Emanuel Berg
Ist Alias ​​ein Befehl? Denn wenn ja, ich hatte es sehr leicht zu tippen alias .="echo Hello".-) (Nun, sudo vim /bin/.war allerdings schwieriger ...)
Alois Mahdal
@AloisMahdal Deshalb sagte ich Befehl Datei . zsh erlaubt auch .() echo Hello. Pdksh auch, aber das .spezielle Builtin hat dort Vorrang.
Stéphane Chazelas
Hoppla, meine Fehlinterpretation ... Interessanter Punkt bezüglich der Präzedenzfälle von pdksh ...
Alois Mahdal
27

Ja, das kann es, und es gibt bereits einige. Wie /usr/bin/X:)

dennis@lightning:~$ ls {/usr{/local,},}/{s,}bin | grep '[A-Z]'
MAKEDEV
amuFormat.sh
GET
HEAD
Mail
POST
X
X11
Xephyr
Xnest
Xorg
NetworkManager

dennis@lightning:~$ zcat ~/.cache/apt-file /archive.ubuntu.com_ubuntu_dists_precise_Contents-i386.gz | tail -n +33 | cut -f1 | grep -P '^(usr/)?s?bin/.*[A-Z]' | wc -l
758

Das sind 758 in Ubuntu 12.04. Vollständige Liste: https://gist.github.com/5264777

Dennis Kaarsemaker
quelle
Nein Xdialog? : o Und Sie sollten grepden Parameter in Anführungszeichen setzen , um zu vermeiden, dass die Shell ihn vor der Ausführung im aktuellen Verzeichnis erweitert.
Manatwork
Haben Sie es nicht auf diesem System installiert :)
Dennis Kaarsemaker
2
Ich möchte darauf bestehen grep, den Parameter des
Zitats anzugeben
1
Nun, es kann auch von der Shell abhängen. Ich habe in meinem Beispiel aus bashGründen der Portabilität Großbuchstaben verwendet, in meinem Ausgangsverzeichnis [A-Z]jedoch "cdfhjmpqrt". Also Groß- und Kleinschreibung beachten.
Manatwork
1
Ganz zu schweigen von zshoder bashs failglobOption. Ich persönlich nenne normalerweise meine temporären Dateien (in ~) a, b, c... und meine Temperatur dirs A, B, C...
Stéphane Chazelas
4

Der bekannteste Befehl ist stty, der auch als verfügbar war STTY. Es war sehr praktisch, das Terminal mit wieder auf normales Verhalten zurückzusetzen STTY SANE.

ott--
quelle
Ich habe /bin/sttyaber sonst nichts. Möchten Sie Ihre Antwort ein wenig ausarbeiten?
Emanuel Berg
2
In der guten alten Zeit war es möglich, dass Ihr Terminal so durcheinander geriet, dass alles in Großbuchstaben geschrieben war. Also tippe aund das Terminal würde sehen A. Um die Vernunft wiederherzustellen, würden Sie den stty saneBefehl verwenden. Abgesehen davon, dass dies jetzt unmöglich ist, war es daher sehr willkommen , sttyverfügbar zu sein STTY. Ich kann mich nicht einmal erinnern,
wann
@ TennisKaarsemaker: WOW! Das ist ein cooles Stück Geschichte!
Emanuel Berg
1
Jungs (ott-- und @DennisKaarsemaker), Sie haben es rückwärts. Ich habe eine andere Antwort zur Klarstellung gepostet .
Stéphane Chazelas
4

Einige Anmerkungen zum historischen STTYBefehl, um einige Ungenauigkeiten in der anderen Antwort und den zugehörigen Kommentaren zu klären :

Frühere Terminals wie das DEC VT05 oder VT50 und die vorherigen Ferndrucker unterstützten nur Großbuchstaben. Dies bedeutete, dass von ihnen niemals Kleinbuchstaben eingegeben werden konnten oder dass sie keinen anderen Buchstaben als Großbuchstaben anzeigen konnten.

Bei Unix wird zwischen Groß- und Kleinschreibung unterschieden und bei den meisten Befehlen wird ein Problem angezeigt. Aus diesem Grund gibt es spezielle Termio / Termios-Modi (und die gibt es in modernen Unices immer noch, obwohl diese Terminals schon lange nicht mehr existieren), um diese zu handhaben.

termio / termios sind die älteren und neueren Schnittstellen zur Steuerung des tty-Treibers unter Unix. In einem Termio (s) ioctlspezifizieren Sie Input, Output, Control Flags ..., die festlegen, wie die elektrischen Signale auf einer seriellen Leitung in Input- und Output-Zeichen und das interne Verhalten des Treibers bei Dingen wie Echo, Echo usw. verarbeitet werden sollen Zeileneditor ... Die meisten davon betreffen virtuelle Terminals wie moderne Unix-VGA-Konsolen oder Pseudoterminals.

Die Befehlszeilenschnittstelle für termio(s)ist der sttyBefehl.

Für die Verarbeitung von Terminals in Großbuchstaben sind drei termio(s)Flags erforderlich:

  • IUCLC(Eingabe von Groß- in Kleinbuchstaben): Eingehende Zeichen werden bei der Eingabe in Kleinbuchstaben umgewandelt. Das heißt, das Avom Terminal gesendete wird als ein a. Das bedeutet , dass mit diesem, ich jetzt geben kann LSauf meine VT50 und die Schale wird gelesen lsaus /dev/ttyX. Ich kann den sttyBefehl jetzt auch ausführen .
  • Mit IUCLCalone und terminal schickte der Treiber echowährend LSder Eingabe lsan das Terminal zurück (damit ich sehen kann, was ich tippe), was nicht angezeigt werden kann. Wir brauchen also auch OLCUC(Ausgabe von Kleinbuchstaben in Großbuchstaben) Wir müssen jeden Kleinbuchstaben in Großbuchstaben umwandeln, bevor wir ihn an das Terminal senden.
  • Nun können wir Unix von einem VT50 aus betreiben, aber was ist, wenn wir jetzt Großbuchstaben eingeben möchten? Hier kommt das xcase lokale Flag ins Spiel. Dies ermöglicht (nur im kanonischen Eingabemodus) das Senden von Großbuchstaben Adurch Eingabe \A, und bei der Ausgabe wird ein Großbuchstabe Aals gerendert \A. (dieser ist nicht unter Linux implementiert)

Der sttyBefehl hat die entsprechenden iuclc, olcucund xcaseEinstellungen und einen Aliasnamen für alle drei: lcase. Die Standardeinstellung und was Sie danach bekommen, stty saneist lcaseaus.

Wenn Sie also mit einem VT50 arbeiten, müssen Sie nur Folgendes ausführen:

stty lcase

in der Lage sein, alles zu tun. Aber Moment mal, wie geht das, wenn Sie nur Großbuchstaben versenden können? Das ist , wo Sie einen benötigen STTYBefehl als Alias für stty, und deshalb sttyunterstützt LCASEals Alias für lcase.

Es gibt keinen solchen SANEAlias, da Sie dies nicht möchten, stty sanewenn Ihr Terminal nur in Großbuchstaben geschrieben ist.

Wenn Sie laufen stty lcaseoder stty olcucversehentlich auf einem normalen Terminal (versuchen Sie es in xtermoder jeder modernen Terminal), das ist , wo Sie eingeben müssen , stty saneum Normalität zurückkehren. Dafür brauchen Sie aber keinen STTYBefehl. Wenn Sie eingeben stty sane, Sie werden sehen STTY SANEEcho zurück, aber das ist nur der angezeigte Text (nicht der eingegebene Befehl) , die übersetzt worden sein , es ist immer noch der stty saneBefehl, der ausgeführt werden soll.

Diejenigen iuclc, olcuc, xcaseverwendeten Flaggen von POSIX spezifiziert werden (und das ist wahrscheinlich , warum es auf Linux implementiert wird , obwohl ich ernsthaft jemand jemals verbunden ein dieses alten Terminals zu einem Linux - System (außer zum Spaß) zweifeln), aber entfernt worden in POSIX: 2001.

Stéphane Chazelas
quelle
2

Auf Fedora 18 hier:

amuFormat.sh
chkrootkitX
enum_chmLib
enumdir_chmLib
extract_chmLib
fakeCMY
GET
HEAD
Mail
oLschema2ldif
POST
smoltDeleteProfile
smoltGui
smoltSendProfile
smp_conf_zone_man_pass.#prelink#.coLtYv
Terminal
test_chmLib
Thunar
X
Xephyr
xfig-Xaw3d
Xorg
Xvnc
MAKEDEV
NetworkManager
amuFormat.sh
chkrootkitX
enum_chmLib
enumdir_chmLib
extract_chmLib
fakeCMY
GET
HEAD
Mail
oLschema2ldif
POST
smoltDeleteProfile
smoltGui
smoltSendProfile
smp_conf_zone_man_pass.#prelink#.coLtYv
Terminal
test_chmLib
Thunar
X
Xephyr
xfig-Xaw3d
Xorg
Xvnc
MAKEDEV
NetworkManager

Für insgesamt 50 (von denen ich die meisten nicht kannte).

vonbrand
quelle
1
50, aber 25 verschiedene.
Stéphane Chazelas
0

Auf Debian Sid, mit zsh und ls -1 $path | grep '[A-Z]', verstehe ich

GET
HEAD
HtFileType
Mail
POST
Pnews
Rnmail
X
X11
Xephyr
Xorg
ircII
amuFormat.sh
hpljP1005
hpljP1006
hpljP1007
hpljP1008
hpljP1505

Bearbeiten: Beachten Sie, dass dies im obigen Befehl die Ziffer und nicht der Buchstabe ist l. Eine Eins wie in einer Spalte.

Emanuel Berg
quelle
1
Mit zsh, laufen:type -m '*[A-Z]*'
Stéphane Chazelas
@StephaneChazelas: OK, Ihr Pfad zeigt den Suchpfad an und enthält auch Shell-Funktionen. Aber meins ist auch zsh-spezifisch: Kleinbuchstaben $pathsind ausnahmsweise nicht in Bash. Je mehr Informationen, desto besser.
Emanuel Berg
1
Ja, ich habe nicht gesagt, dass Sie falsch liegen, sondern nur eine Alternative vorgeschlagen (obwohl ich der Meinung bin, dass dies nicht die beste Formulierung ist). Beachten Sie, dass dies $pathnicht zsh-spezifisch ist. Es kommt von dort, csh/tcshwo Ihr Befehl auch funktioniert.
Stéphane Chazelas
@StephaneChazelas: Aha, das ist interessant! Nein, mein Befehl ist nicht "falsch", aber ich stimme zu, dass Ihr Befehl besser ist, da es sinnvoll ist, Shell-Funktionen und Aliase einzuschließen. Zumindest für mich, denn wenn ich meinen Computer benutze, ist es mir egal, ob es sich um eine Binärdatei, ein Skript, eine Funktion, einen Alias ​​oder was auch immer handelt, solange ich es ausführen kann und es seinen Job macht. (Ich denke, das -mist für "Match".)
Emanuel Berg