- Zunächst können Sie diesen Artikel hier auf Russisch lesen.
Eines Abends, als ich das
Regieren von regulären Ausdrücken von Jeffrey Friedl las, wurde mir klar, dass selbst wenn Sie über alle Unterlagen und viel Erfahrung verfügen, es viele Tricks geben kann, die von verschiedenen Menschen entwickelt und für sich selbst eingesperrt wurden. Alle Menschen sind unterschiedlich. Und Techniken, die für bestimmte Menschen offensichtlich sind, sind für andere möglicherweise nicht offensichtlich und sehen für die dritte Person wie eine seltsame Magie aus. Übrigens habe ich hier bereits einige solcher Momente beschrieben
(auf Russisch) .
Für den Administrator oder den Benutzer ist die Befehlszeile nicht nur ein Tool, das alles kann, sondern auch ein hochgradig angepasstes Tool, das für immer entwickelt werden kann. Kürzlich gab es einen übersetzten Artikel über einige nützliche Tricks in CLI. Ich habe jedoch das Gefühl, dass der Übersetzer nicht genügend Erfahrung mit CLI hat und die beschriebenen Tricks nicht befolgt hat, sodass viele wichtige Dinge übersehen oder missverstanden werden können.
Unter dem Strich - ein Dutzend Tricks in der Linux-Shell aus meiner persönlichen Erfahrung.
Hinweis: Alle Skripte und Beispiele im Artikel wurden so weit wie möglich speziell vereinfacht. Vielleicht finden Sie mehrere Tricks völlig nutzlos - vielleicht ist dies der Grund. Aber teilen Sie auf jeden Fall Ihre Meinung in den Kommentaren!
1. Teilen Sie die Zeichenfolge mit variablen Erweiterungen
Menschen verwenden oft
geschnitten oder sogar
awk , um einen Teil der Schnur nach Muster oder mit Trennzeichen zu subtrahieren.
Außerdem verwenden viele Leute eine Teilzeichenfolgen-Bash-Operation mit $ {VARIABLE: start_position: length}, die sehr schnell funktioniert.
Bash bietet jedoch eine leistungsstarke Möglichkeit zum Bearbeiten von Textzeichenfolgen mit #, ##,% und %% - es werden
Bash-Variablenerweiterungen genannt .
Mit dieser Syntax können Sie das Notwendige nach Muster schneiden, ohne externe Befehle ausführen zu müssen, sodass es sehr schnell funktioniert.
Das folgende Beispiel zeigt, wie die dritte Spalte (Shell) aus der Zeichenfolge abgerufen wird, in der durch Doppelpunkt "Benutzername: Homedir: Shell" getrennte Werte mit
cut oder mit variablen Erweiterungen getrennt werden (wir verwenden die
*: Maske und den Befehl ##, was bedeutet: cut alle Zeichen links bis zum letzten gefundenen Doppelpunkt):
$ STRING="username:homedir:shell" $ echo "$STRING"|cut -d ":" -f 3 shell $ echo "${STRING##*:}" shell
Die zweite Option startet den untergeordneten Prozess (
Ausschneiden ) nicht und verwendet überhaupt keine Pipes, was viel schneller funktionieren sollte. Und wenn Sie das Bash-Subsystem in Fenstern verwenden, in denen sich die Rohre kaum bewegen, ist der Geschwindigkeitsunterschied
erheblich .
Sehen wir uns ein Beispiel für Ubuntu an - führen Sie unseren Befehl 1000 Mal in einer Schleife aus
$ cat test.sh
Ergebnisse $ ./test.sh using cut real 0m0.950s user 0m0.012s sys 0m0.232s using
Der Unterschied ist mehrere Dutzend Mal!
Das obige Beispiel ist natürlich zu künstlich. Im realen Beispiel arbeiten wir nicht mit einer statischen Zeichenfolge, wir möchten eine reale Datei lesen. Und für den Befehl '
cut ' leiten wir einfach / etc / passwd dorthin um. Im Fall von ## müssen wir eine Schleife erstellen und die Datei mit dem internen Befehl '
read '
lesen . Wer wird diesen Fall gewinnen?
$ cat test.sh
Ergebnis $ ./test.sh $ ./test.sh using cut real 0m0.827s user 0m0.004s sys 0m0.208s using
Keine Kommentare =)
Noch ein paar Beispiele:
Extrahieren Sie den Wert nach dem gleichen Zeichen:
$ VAR="myClassName = helloClass" $ echo ${VAR##*= } helloClass
Text in runden Klammern extrahieren:
$ VAR="Hello my friend (enemy)" $ TEMP="${VAR##*\(}" $ echo "${TEMP%\)}" enemy
2. Bash Autocompletion mit Tab
Das Bash-Completion-Paket ist Teil fast jeder Linux-Distribution. Sie können es in /etc/bash.bashrc oder /etc/profile.d/bash_completion.sh aktivieren, aber normalerweise ist es bereits standardmäßig aktiviert. Im Allgemeinen ist die automatische Vervollständigung einer der ersten praktischen Momente auf der Linux-Shell, die ein Neuling zuerst trifft.
Aber die Tatsache, dass nicht jeder alle Bash-Completion-Funktionen nutzt und meiner Meinung nach völlig vergebens ist. Zum Beispiel weiß nicht jeder, dass die automatische Vervollständigung nicht nur mit Dateinamen funktioniert, sondern auch mit Aliasnamen, Variablennamen, Funktionsnamen und für einige Befehle sogar mit Argumenten. Wenn Sie sich mit Autocomplete-Skripten befassen, bei denen es sich tatsächlich um Shell-Skripte handelt, können Sie sogar
Autocomplete für Ihre eigene Anwendung oder Ihr eigenes Skript
hinzufügen .
Aber kommen wir zurück zu den Aliasnamen.
Sie müssen keine PATH-Variable bearbeiten oder Dateien im angegebenen Verzeichnis erstellen, um einen Alias auszuführen. Sie müssen sie nur zum Profil oder zum Startskript hinzufügen und von jedem Ort aus ausführen.
Normalerweise verwenden wir Kleinbuchstaben für Dateien und Verzeichnisse in * nix, daher kann es sehr bequem sein, Aliase in Großbuchstaben zu erstellen. In diesem Fall wird die Bash-Vervollständigung Ihren Befehl fast mit einem einzigen Buchstaben
erraten :
$ alias TAsteriskLog="tail -f /var/log/asteriks.log" $ alias TMailLog="tail -f /var/log/mail.log" $ TA[tab]steriksLog $ TM[tab]ailLog
3. Bash Autocompletion mit Tab - Teil 2
In komplizierteren Fällen möchten Sie wahrscheinlich Ihre persönlichen Skripte in $ HOME / bin ablegen.
Aber wir haben Funktionen in Bash.
Funktionen erfordern keinen Pfad oder separate Dateien. Und (Aufmerksamkeits-) Bash-Vervollständigung funktioniert auch mit Funktionen.
Erstellen wir die Funktion LastLogin in
.profile (vergessen Sie nicht, .profile neu zu laden):
function LastLogin { STRING=$(last | head -n 1 | tr -s " " " ") USER=$(echo "$STRING"|cut -d " " -f 1) IP=$(echo "$STRING"|cut -d " " -f 3) SHELL=$( grep "$USER" /etc/passwd | cut -d ":" -f 7) echo "User: $USER, IP: $IP, SHELL=$SHELL" }
(Eigentlich ist es nicht wichtig, was diese Funktion tut, es ist nur ein Beispielskript, das wir in das separate Skript oder sogar in den Alias einfügen können, aber die Funktion könnte besser sein) .
In der Konsole (bitte beachten Sie, dass der Funktionsname einen Großbuchstaben enthält, um die Bash-Vervollständigung zu beschleunigen):
$ L[tab]astLogin User: saboteur, IP: 10.0.2.2, SHELL=/bin/bash
4.1. Sensible Daten
Wenn Sie vor einem Befehl in der Konsole Leerzeichen einfügen, wird dieser nicht im Befehlsverlauf angezeigt. Wenn Sie also ein einfaches Textkennwort in den Befehl eingeben müssen, ist dies eine gute Möglichkeit, diese Funktion zu verwenden. Schauen Sie sich das folgende Beispiel an und geben Sie
"Hallo" ein 2 " wird nicht in der Geschichte angezeigt:
$ echo "hello" hello $ history 2 2011 echo "hello" 2012 history 2 $ echo "my password secretmegakey"
Es ist optionalEs ist normalerweise standardmäßig aktiviert, aber Sie können dieses Verhalten in der folgenden Variablen konfigurieren:
export HISTCONTROL = ignoreboth
4.2. Sensible Daten in Befehlszeilenargumenten
Sie möchten einige Shell-Skripte in git speichern, um sie für mehrere Server freizugeben, oder sie sind möglicherweise Teil des Anwendungsstart-Skripts. Und Sie möchten, dass dieses Skript eine Verbindung zur Datenbank herstellt oder andere Aktionen ausführt, für die Anmeldeinformationen erforderlich sind.
Natürlich ist es eine schlechte Idee, Anmeldeinformationen im Skript selbst zu speichern, da git nicht sicher ist.
Normalerweise können Sie Variablen verwenden, die bereits in den Zielumgebungen definiert wurden, und Ihr Skript enthält nicht die Kennwörter selbst.
Sie können beispielsweise in jeder Umgebung ein kleines Skript mit 700 Berechtigungen erstellen und es mit dem
Quellbefehl aus dem Hauptskript aufrufen:
secret.sh PASSWORD=LOVESEXGOD
myapp.sh source ~/secret.sh sqlplus -l user/"$PASSWORD"@database:port/sid @mysqfile.sql
Aber es ist nicht sicher.
Wenn sich jemand anderes bei Ihrem Host anmelden kann, kann er einfach den Befehl
ps ausführen und Ihren sqlplus-Prozess mit den gesamten Befehlszeilenargumenten einschließlich Kennwörtern anzeigen. Daher sollten sichere Tools normalerweise in der Lage sein, Kennwörter / Schlüssel / vertrauliche Daten direkt aus Dateien zu lesen.
Zum Beispiel - Secure
SSH hat einfach keine Optionen, um ein Passwort in der Kommandozeile anzugeben. Er kann jedoch den SSH-Schlüssel aus der Datei lesen (und Sie können sichere Berechtigungen für die SSH-Schlüsseldatei festlegen).
Und nicht sichere wget haben eine Option "--password", mit der Sie ein Passwort in der Kommandozeile eingeben können. Und während wget ausgeführt wird, kann jeder den Befehl ps ausführen und das von Ihnen angegebene Passwort anzeigen.
Wenn Sie viele vertrauliche Daten haben und diese über Git steuern möchten, ist die einzige Möglichkeit die Verschlüsselung. Sie geben also in jede Zielumgebung nur das Hauptkennwort und alle anderen Daten ein, die Sie verschlüsseln und an git senden können. Über die openssl-CLI-Schnittstelle können Sie über die Befehlszeile mit verschlüsselten Daten arbeiten. Hier ist ein Beispiel zum Ver- und Entschlüsseln über die Befehlszeile:
Die Datei secret.key enthält den Hauptschlüssel - eine einzelne Zeile:
$ echo "secretpassword" > secret.key; chmod 600 secret.key
Verwenden wir aes-256-cbc, um eine Zeichenfolge zu verschlüsseln:
$ echo "string_to_encrypt" | openssl enc -pass file:secret.key -e -aes-256-cbc -a U2FsdGVkX194R0GmFKCL/krYCugS655yLhf8aQyKNcUnBs30AE5lHN5MXPjjSFML
Sie können diese verschlüsselte Zeichenfolge in jede in git oder an einem anderen Ort gespeicherte Konfigurationsdatei einfügen - ohne secret.key ist es fast unmöglich, sie zu entschlüsseln.
Um den gleichen Befehl zu entschlüsseln, ersetzen Sie einfach -e durch -d:
$ echo 'U2FsdGVkX194R0GmFKCL/krYCugS655yLhf8aQyKNcUnBs30AE5lHN5MXPjjSFML' | openssl enc -pass file:secret.key -d -aes-256-cbc -a string_to_encrypt
5. Der Befehl grep
Alle sollten den Befehl grep kennen. Und sei freundlich mit regulären Ausdrücken. Und oft kann man so etwas schreiben wie:
tail -f application.log | grep -i error
Oder sogar so:
tail -f application.log | grep -i -P "(error|warning|failure)"
Aber vergessen Sie nicht, dass grep viele wunderbare Möglichkeiten hat. Beispiel: -v, das Ihre Suche zurücksetzt und alle Nachrichten außer "info" anzeigt:
tail -f application.log | grep -v -i "info"
Zusätzliches Zeug:
Option -P ist sehr nützlich, da grep standardmäßig einen ziemlich veralteten "grundlegenden regulären Ausdruck:" verwendet und -P PCRE aktiviert, das nicht einmal etwas über Gruppierung weiß.
-i ignoriert den Fall.
--line-buffered parses line sofort, anstatt darauf zu warten, den Standard-4k-Puffer zu erreichen (nützlich für tail -f | grep).
Wenn Sie den regulären Ausdruck gut kennen, können Sie mit --only-matching / -o wirklich großartige Dinge mit dem Schneiden von Text tun. Vergleichen Sie einfach die nächsten beiden Befehle, um die Shell von myuser zu extrahieren:
$ grep myuser /etc/passwd| cut -d ":" -f 7 $ grep -Po "^myuser(:.*){5}:\K.*" /etc/passwd
Der zweite Befehl sieht kompilierter aus, führt jedoch nur
grep anstelle von
grep und
cut aus , sodass die Ausführung weniger Zeit in Anspruch nimmt.
6. So reduzieren Sie die Größe der Protokolldatei
Wenn Sie in * nix die Protokolldatei löschen, die derzeit von einer Anwendung verwendet wird, können Sie nicht nur alle Protokolle entfernen, sondern auch verhindern, dass die Anwendung bis zum Neustart neue Protokolle schreibt.
Da der Dateideskriptor nicht den Dateinamen, sondern die iNode-Struktur öffnet und die Anwendung weiterhin in den Dateideskriptor in die Datei schreibt, die keinen Verzeichniseintrag hat, wird diese Datei automatisch gelöscht, nachdem die Anwendung vom Dateisystem gestoppt wurde (
Ihre Anwendung kann dies) Öffnen und schließen Sie die Protokolldatei jedes Mal, wenn Sie etwas schreiben möchten, um ein solches Problem zu vermeiden, dies beeinträchtigt jedoch die Leistung .
So löschen Sie die Protokolldatei, ohne sie zu löschen:
echo "" > application.log
Oder wir können den Befehl kürzen verwenden:
truncate --size=1M application.log
Erwähnen Sie, dass dieser Befehl zum Abschneiden den Rest der Datei löscht, sodass Sie die neuesten Protokollereignisse verlieren. Überprüfen Sie ein weiteres Beispiel zum Speichern der letzten 1000 Zeilen:
echo "$(tail -n 1000 application.log)" > application.log
PS Unter Linux haben wir Standard Service Rotatelog. Sie können Ihre Protokolle zum automatischen Abschneiden / Drehen hinzufügen oder vorhandene Protokollbibliotheken verwenden, die dies für Sie tun können (wie log4j in Java).7. Watch passt auf dich auf!
Es gibt eine Situation, in der Sie darauf warten, dass ein Ereignis beendet wird. Zum Beispiel, während sich ein anderer Benutzer bei der Shell anmeldet (Sie führen
den Befehl
who kontinuierlich aus), oder jemand die Datei mit scp oder ftp auf Ihren Computer kopieren sollte und Sie auf den Abschluss warten (ls Dutzende Male wiederholen).
In solchen Fällen können Sie verwenden
watch <command>
Standardmäßig wird alle 2 Sekunden mit Vorab-Löschen des Bildschirms ausgeführt, bis Strg + C gedrückt wird. Sie können konfigurieren, wie oft ausgeführt werden soll.
Dies ist sehr nützlich, wenn Sie Live-Protokolle anzeigen möchten.
8. Bash-Sequenz
Es gibt ein sehr nützliches Konstrukt zum Erstellen von Bereichen. Zum Beispiel statt so etwas:
for srv in 1 2 3 4 5; do echo "server${srv}";done server1 server2 server3 server4 server5
Sie können Folgendes schreiben:
for srv in server{1..5}; do echo "$srv";done server1 server2 server3 server4 server5
Sie können auch den Befehl
seq verwenden , um formatierte Bereiche zu generieren. Zum Beispiel können wir
seq verwenden , um Werte zu erstellen, die automatisch durch die Breite angepasst werden (00, 01 anstelle von 0, 1):
for srv in $(seq -w 5 10); do echo "server${srv}";done server05 server06 server07 server08 server09 server10
Ein weiteres Beispiel mit Befehlssubstitution - Dateien umbenennen. Um den Dateinamen ohne Erweiterung zu erhalten, verwenden wir den Befehl '
basename ':
for file in *.txt; do name=$(basename "$file" .txt);mv $name{.txt,.lst}; done
Auch noch kürzer mit '%':
for file in *.txt; do mv ${file%.txt}{.txt,.lst}; done
PS Zum Umbenennen der Dateien können Sie das Tool "
Umbenennen " verwenden, das viele Optionen bietet.
Ein weiteres Beispiel: Erstellen Sie eine Struktur für ein neues Java-Projekt:
mkdir -p project/src/{main,test}/{java,resources}
Ergebnis project/ !--- src/ |--- main/ | |-- java/ | !-- resources/ !--- test/ |-- java/ !-- resources/
9. Schwanz, mehrere Dateien, mehrere Benutzer ...
Ich habe
Multitail erwähnt, um Dateien zu lesen und mehrere Live-Protokolle
anzusehen . Es wird jedoch nicht standardmäßig bereitgestellt, und Berechtigungen zum Installieren von Objekten sind nicht immer verfügbar.
Aber Standardschwanz kann es auch:
tail -f /var/logs/*.log
Erinnern wir uns auch an Benutzer, die 'tail -f'-Aliase verwenden, um Anwendungsprotokolle zu überwachen.
Mehrere Benutzer können Protokolldateien gleichzeitig mit 'tail -f' anzeigen. Einige von ihnen sind mit ihren Sitzungen nicht sehr genau. Sie könnten aus irgendeinem Grund 'tail -f' im Hintergrund lassen und es vergessen.
Wenn die Anwendung neu gestartet wurde, gibt es diese 'tail-f'-Prozesse, die beobachten, dass nicht vorhandene Protokolldateien mehrere Tage oder sogar Monate hängen bleiben können.
Normalerweise ist es kein großes Problem, aber nicht ordentlich.
Falls Sie zum Überwachen des Protokolls einen Alias verwenden, können Sie diesen Alias mit der Option --pid ändern:
alias TFapplog='tail -f --pid=$(cat /opt/app/tmp/app.pid) /opt/app/logs/app.log'
In diesem Fall werden alle
Endpunkte automatisch beendet, wenn die Zielanwendung neu gestartet wird.
10. Erstellen Sie eine Datei mit der angegebenen Größe
dd war eines der beliebtesten Tools für die Arbeit mit Block- und Binärdaten. Beispiel: Eine mit Null gefüllte 1-MB-Datei wird erstellt:
dd if=/dev/zero of=out.txt bs=1M count=10
Aber ich empfehle die Verwendung von
Fallocate :
fallocate -l 10M file.txt
Auf Dateisystemen, die die Zuweisungsfunktion unterstützen (xfs, ext4, Btrfs ...), wird
fallocate im Gegensatz zum dd-Tool sofort ausgeführt. Zuweisen bedeutet außerdem, dass Blöcke tatsächlich zugewiesen werden und keine Ersatzdatei erstellt wird.
11. xargs
Viele Leute kennen den beliebten Befehl
xargs . Aber nicht alle verwenden zwei der folgenden Optionen, die Ihr Skript erheblich verbessern könnten.
Erstens: Sie können eine sehr lange Liste von zu verarbeitenden Argumenten erhalten, die die Befehlszeilenlänge überschreiten kann (standardmäßig ~ 4 kb).
Sie können die Ausführung jedoch mit der Option -n einschränken, sodass
xargs den Befehl mehrmals ausführt und jeweils eine bestimmte Anzahl von Argumenten sendet:
$
Gehen Sie voran. Das Verarbeiten einer langen Liste kann viel Zeit in Anspruch nehmen, da sie in einem einzelnen Thread ausgeführt wird. Wenn wir jedoch mehrere Kerne haben, können wir
xargs anweisen , parallel zu laufen:
echo 1 2 3 4 5 6 7 8 9 10| xargs -n 2 -P 3 echo
Im obigen Beispiel
weisen wir
xargs an, die Liste in 3 Threads zu verarbeiten. Jeder Thread akzeptiert und verarbeitet 2 Argumente pro Ausführung. Wenn Sie nicht wissen, wie viele Kerne Sie haben, können Sie dies mit "
nproc " optimieren:
echo 1 2 3 4 5 6 7 8 9 10 | xargs -n 2 -P $(nproc) echo
12. schlafen? während? lesen!
Einige Zeit müssen Sie einige Sekunden warten. Oder warten Sie auf Benutzereingaben mit read:
read -p "Press any key to continue " -n 1
Sie können dem Lesebefehl jedoch einfach eine Timeout-Option hinzufügen, und Ihr Skript wird für eine bestimmte Anzahl von Sekunden angehalten. Bei einer interaktiven Ausführung kann der Benutzer das Warten jedoch problemlos überspringen.
read -p "Press any key to continue (auto continue in 30 seconds) " -t 30 -n 1
Sie können also einfach den Schlafbefehl vergessen.
Ich vermute, dass nicht alle meine Tricks interessant aussehen, aber es schien mir, dass ein Dutzend eine gute Zahl zum Ausfüllen sind.
An dieser Stelle verabschiede ich mich und bin dankbar für die Teilnahme an der Umfrage.
Natürlich kannst du das oben Genannte diskutieren und deine coolen Tricks in den Kommentaren teilen!