Ich habe ein alias
Set für meinen rm
Befehl. Wenn ich einen alias
Befehl ausführe , erhalte ich diesen als Ausgabe.
alias rm='rm -i'
Wenn ich jetzt den rm
Befehl ausführe , funktioniert er wie erwartet.
rm ramesh
rm: remove regular empty file `ramesh'? y
Jetzt lernte ich die Systemaufrufe, die aufgerufen werden, wenn ich einen Befehl ausführe. Dafür habe ich strace
von hier aus den Befehl kennengelernt, der mir die Dateien auflistet, die aufgerufen werden, wenn ich einen Befehl ausführe. Der Befehl ist wie folgt.
strace -ff -e trace=file rm ramesh 2>&1
Der Befehl funktioniert einwandfrei, außer dass er meine Aliase ignoriert, die ich für meinen rm
Befehl eingerichtet habe. Die Datei wird gelöscht, ohne dass der Benutzer dazu aufgefordert wird.
Von daher ist strace
Aliase wie diese ignorieren? Wenn ja, warum ist es so?
BEARBEITEN:
Ich bin type -a rm
mir nicht sicher, ob dies etwas zu tun hat, aber ich gebe die Ausgabe als,
rm is aliased to `rm -i'
rm is /bin/rm
Berücksichtigt man /bin/rm
in diesem Fall, warum der Benutzer nicht vor dem Löschen aufgefordert wird?
strace
ignoriert Aliase nicht, da dies bedeuten würde, dass überhaupt etwas zu ignorieren wäre. Ein Alias ist ein Merkmal der Shell.strace
ist ein anderes Programm, und innerhalbstrace
des Konzepts der Aliase existiert nicht, daher gibt es nichts zu ignorieren. Die vom Kernel bereitgestellte API zum Ausführen von Programmen enthält ebenfalls kein Aliase-Konzept. Daher kann die Shell auf keinen Fall einen Hinweis auf Aliase geben, selbst wenn dies gewünscht wird.strace
einen Alias möchten , müssen Siestrace
die Shell verwenden, die den Alias implementiert. Es gibt einige Ansätze, die Sie dazustrace -p $$ &
strace bash
strace sh -c 'rm ramesh'
Antworten:
strace
läuft nichtrm -i
aus dem gleichen Grund wie:wird nicht ausgegeben
rm -i
.Aliase sind ein Merkmal einiger Shells, mit denen einige Zeichenfolgen automatisch durch andere ersetzt werden können, wenn sie sich in der Befehlsposition befinden.
Im:
Die Muscheln erweitern das auf:
und das durchläuft eine weitere Interpretationsrunde, die in diesem Fall zur Ausführung des
whatever
Befehls führt.Aliase werden nur erweitert, wenn sie an der Befehlsposition gefunden werden (als erstes Wort einer Befehlszeile).
zsh
unterstützt globale Aliase.Du könntest es tun:
Aber du würdest nicht wollen, denn das würde bedeuten:
würde
rm -i
zum Beispiel ausgeben .quelle
strace
Verwendet diePATH
Umgebungsvariable, um das zu verfolgende Programm zu lokalisieren, anstatt es über die Shell auszuführen (was die Ausgabe überladen würde). Ein Shell-Alias ist kein Programm, sondern eine Funktion der Shell und wird daherstrace
ignoriert.Laufen
strace strace rm
ist ziemlich aufschlussreich und interessant rekursiv.quelle
Ein Alias ist eine Funktion Ihrer Shell. Strace führt den Befehl jedoch direkt aus (
execve
wahrscheinlich mit), wobei die Shell nicht beteiligt ist. (Wenn strace den angegebenen Befehl über die Shell ausführt, enthält die Ausgabe von strace alle Shell-Ausführungs-Systemaufrufe und nicht nur die aus dem interessierenden Prozess.)Darüber hinaus versucht
strace rm ramesh
die interaktive Shell beim Ausführen nicht, Ihren Alias in den Argumenten zu ersetzen, da dies für alle schrecklich verwirrend wäre. Die Shell erweitert nur Aliase, die an der ersten Position in einer Befehlszeile angezeigt werden.quelle
strace verwendet
execve c function
wiefind command
, jedoch könnenfind uses exec function
Sie nicht verwendenaliases
,built-in shell command
oder so weiter.Du musst:
quelle
Um auf der Antwort von Stéphane Chazelas aufzubauen, wenn Sie definieren
(mit einem Leerzeichen am Ende) dann der Befehl
wird verarbeitet als
Aber selbst dies funktioniert nur für das erste Wort nach dem
strace
, sodass es nicht direkt auf Ihr Beispiel zutrifft (wo Sie intervenierende Optionen haben). Aber wenn Sie definierendann
wird verarbeitet als
quelle
Keine Aliase hier
Nehmen wir an, wir haben die Alias-Definition
alias rm='rm -i'
in unserer~/.bashrc
. Der Alias fügt die Option zum Auffordern vor dem Entfernen jeder Datei hinzu:Es ist nicht die Schuld,
strace
dass der Alias nicht verwendet wurde:Es hat einfach nichts mit Aliasen zu tun.
Im Befehl
Die Wörter
rm
und./file
sind vorerst nur Argumente für strace - die Shell kann den Alias nicht erweiternrm
, da sie nicht wissen kann, dass strace diese Argumente später als Befehl verwendet.Im Allgemeinen können Befehls-Aliase nur dort verwendet werden, wo Befehle verwendet werden können.
Aliase sind eine Funktion der Shell und verwenden
strace
überhaupt keine Shell, wenn der Befehl über die Befehlszeile aufgerufen wird. Es wirdexec()
stattdessen mit den Befehlen und Argumenten aus der eigenen Befehlszeile verwendet.Innerhalb von
strace
, wird der Befehl mit etwas ähnlichem genannt werdenexec("rm", "file")
, undexec()
findet/bin/rm
in PATH - ohne eine Shell zu verwenden.Explizite Shell
Warum nicht eine Shell in den
strace
Befehl aufnehmen?Hmm ... das hat nicht funktioniert.
rm
habe gerade die Datei ohne-i
Aufforderung gelöscht .Interaktive Aliase
Aliase werden normalerweise nur in interaktiven Shells aktiviert, den tatsächlichen Befehlszeilen in einem Terminal.
Bei unserem Beispielalias ist leicht zu erkennen, warum dies sinnvoll ist: Wenn der
rm -i
Alias in Shell-Skripten erweitert würde, würden sie beim ersten Mal hängen bleiben, ohne dass jemandrm
zum Drücken da wärey
.Aliase werden von der Shell-Option gesteuert
expand_aliases
. Wir könnten die Option mit einstellenbash +O expand_aliases -c ...
. Das reicht aber nicht, denn die nicht interaktive Shell liest auch nicht~/.bashrc
. Das heißt, unser Alias wird nicht nur durch die Option ausgeschaltet, sondern auch nicht einmal definiert.Vorgeben, interaktiv zu sein
Die einfache Möglichkeit, beide Teile zu handhaben, besteht darin, die Befehlszeilenoption
-i
zu verwenden, damit die Shell so tut, als wäre sie interaktiv:Schließlich wurde der
-i
Alias verwendet!Beachten Sie, dass Sie normalerweise keine Shells verwenden würden, die mit der
-i
Option zum Erstellen von Skripten ausgeführt werden, selbst wenn Sie beispielsweise Ihre Aliase verfügbar haben möchten.quelle