Fehler bei der Verwendung der Befehlszeile als Bash-Alias ​​unter Linux

2869
cfischer

Ich möchte die folgende Befehlszeilenfolge als Bash-Alias ​​speichern:

grep `date '+%d/%b/%Y'` access.logs | egrep 2765330645ae47d292c9ceac725d744e.py |awk '' | sort |uniq -c -w15 |sort -n 

Es funktioniert gut von der Kommandozeile aus, schlägt jedoch fehl, wenn ich versuche, es als Alias ​​zu setzen. Ich habe versucht, Folgendes zu .bash_profile hinzuzufügen:

alias downloads="grep `date '+%d/%b/%Y'` access.logs | egrep 2765330645ae47d292c9ceac725d744e.py |awk '' | sort |uniq -c -w15 |sort -n" 

und ich bekomme die folgenden Fehler:

-bash-3.2$ downloads awk:  awk: ^ syntax error awk:  awk: ^ syntax error awk:  awk: ^ syntax error awk:  awk: ^ syntax error awk:  awk: ^ syntax error awk:  awk: ^ syntax error 

Was mache ich falsch????

4

5 Antworten auf die Frage

6
A Dwarf

Ich bin ein bisschen grün unter Linux, daher bin ich mir nicht sicher, warum es nicht funktioniert. Sie können jedoch stattdessen eine Funktion verwenden.

Erstellen Sie in .profile / .bashrc eine neue Funktion:

downloads() { grep `date '+%d/%b/%Y'` access.logs | egrep 2765330645ae47d292c9ceac725d744e.py |awk '' | sort |uniq -c -w15 |sort -n; } 

Das funktioniert genau wie ein Alias.

Ah! Nagul weiß warum es nicht funktioniert :) A Dwarf vor 14 Jahren 1
(+1) Wenn ich keinen triftigen Grund hätte, einen Alias ​​einer Funktion vorzuziehen, würde ich das eigentlich vorziehen. Dies ist sauberer und offensichtlicher als die verdeckte Version des Alias. nagul vor 14 Jahren 0
5
Jonathan Leffler

Ehrlich gesagt, wenn ein Befehl so groß wird, würde ich es zu einem Skript und nicht zu einem Alias ​​machen. Ein Vorteil eines Skripts ist, dass Sie es mit mehr Dateien als nur mit 'access.logs' arbeiten lassen.

Diese Befehlsfolge umfasst sowohl einfache als auch hintere Anführungszeichen - was immer zum Spaß beiträgt. Im Allgemeinen ist es besser, $(command args)anstelle von Anführungszeichen zu verwenden.

Wenn Sie den Alias ​​in doppelte Anführungszeichen setzen, werden die Befehle in Anführungszeichen ausgeführt, wenn der Alias ​​erstellt wird - es sei denn, die Shell interpretiert die Dinge bei der Definition des Alias ​​anders. Außerdem werden $varAusdrücke in Anführungszeichen ausgewertet, sodass Ihre awkFehler zeigen, dass Sie in der aktuellen Shell keine Argumente haben.

Wenn Sie also einen Alias ​​verwenden müssen, müssen Sie wahrscheinlich den gesamten Ausdruck in einfache Anführungszeichen setzen, und für jedes einzelne Anführungszeichen, das im Ausdruck angezeigt wird, dieses durch die Sequenz quote-backslash-quote-quote: ersetzen '\''. Das erste Anführungszeichen beendet die aktuelle Anführungszeichenfolge. Das Backslash-Zitat steht für ein buchstäbliches Zitat. Das letzte Zitat startet die zitierte Zeichenfolge neu.

Das führt zu:

alias downloads='grep `date '\''+%d/%b/%Y'\''` access.logs | egrep 2765330645ae47d292c9ceac725d744e.py | awk '\'''\'' | sort | uniq -c -w15 | sort -n' 
Das ist ein guter Rat! Sie können auch eine 'Bash-Funktion' erstellen, in der Tat ist jedoch ein Skript zu bevorzugen (zumindest für variable Bereiche). Funktionen werden nicht von Subshells vererbt, aber Skripte können immer noch über $ PATH gefunden werden ericslaw vor 14 Jahren 0
"Funktionen werden nicht von Subshells vererbt" - Sie können jedoch `export -f functionname` ausführen Dennis Williamson vor 14 Jahren 1
4
nagul

Da der Alias ​​in Anführungszeichen definiert ist, wird der Date- Befehl zum Zeitpunkt der Definition des Alias ​​ausgeführt, und die $1Variablen werden ebenfalls erweitert. Sie können dies überprüfen, indem Sie den Alias ​​nach der Definition nachschlagen:

$ alias downloads="grep `date '+%d/%b/%Y'` access.logs | egrep 2765330645ae47d292c9ceac725d744e.py |awk '' | sort |uniq -c -w15 |sort -n" $ alias downloads alias downloads='grep 27/Sep/2009 access.logs | egrep 2765330645ae47d292c9ceac725d744e.py |awk '\'''\'' | sort |uniq -c -w15 |sort -n' 

Sie sollten dieses Problem beheben, indem er die Flucht Datum Aufruf und die $1Variablen:

$ alias downloads="grep \`date '+%d/%b/%Y'\` access.logs | egrep 2765330645ae47d292c9ceac725d744e.py |awk '' | sort |uniq -c -w15 |sort -n" $ alias downloads alias downloads='grep `date '\''+%d/%b/%Y'\''` access.logs | egrep 2765330645ae47d292c9ceac725d744e.py |awk '\'''\'' | sort |uniq -c -w15 |sort -n' 

Prüfen Sie, ob Sie dies erfolgreich ausführen können. Im Idealfall würden Sie den Alias ​​in einfachen Anführungszeichen definieren, aber das Vorhandensein von einfachen Anführungszeichen innerhalb des Alias ​​selbst macht dies in Ihrer Situation schwierig.

3
Dennis Williamson

Eine andere Variante ist die Verwendung von einfachen Anführungszeichen für die äußeren und die Flucht und die inneren Zitate. Sie können wählen, welche Methode (diese oder die in der Antwort von Nagul ) die am wenigsten hässlichen Ergebnisse für eine bestimmte Situation ergibt.

alias downloads='grep $(date '\''+%d/%b/%Y'\'') access.logs | egrep 2765330645ae47d292c9ceac725d744e.py |awk '\'''\'' | sort |uniq -c -w15 |sort -n' 

Sie werden wahrscheinlich feststellen, dass dies aliassowieso ausgedruckt wird, wenn Sie allen Dollarzeichen entgehen.

Ich habe die Freiheit, die in Backticks Wechsel $()für Lesbarkeit und Vielseitigkeit .

Wenn Sie die Methode $()des Naguls (einschließlich doppelter Anführungszeichen für die äußeren) und anstelle von Backticks verwenden, müssen Sie nur Dollarzeichen entkommen.

alias downloads="grep \$(date '+%d/%b/%Y') access.logs | egrep 2765330645ae47d292c9ceac725d744e.py |awk '' | sort |uniq -c -w15 |sort -n" 

Dies ermöglicht eine leicht zu merkende und sehr konsistente Methode.

0
cokedude

Wie würden Sie den Wert, den Sie von awk erhalten haben, verwenden und als Variable speichern? Damit fange ich an.

alias xx2='xrandr | awk '\''$2=="connected" END'\'''

Das versuche ich zu tun.

VAR=$(xrandr | awk '$2=="connected" END'); xrandr --output $VAR --mode 1024x768 --rate 60; xrandr --output LVDS1 --left-of $VAR; xrandr --output LVDS1 --primary; unset VAR;

Das war meine erste Idee. Ich habe gesehen, dass VAR nach dem Versuch, OMG zu öffnen, keinen Wert erhält.

alias xx2='VAR=$(xrandr | awk '\''$2=="connected" END'\''); echo $VAR > OMG'