GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Weitere dumme Bash-Tricks:Variablen, Suchen, Dateideskriptoren und Remote-Operationen

Dieser Blogbeitrag ist der zweite von zwei, der einige praktische Tipps und Tricks behandelt, um das Beste aus der Bash-Shell herauszuholen. In Teil eins behandelte ich die Geschichte, das letzte Argument, die Arbeit mit Dateien und Verzeichnissen, das Lesen von Dateien und Bash-Funktionen. In diesem Abschnitt behandle ich Shell-Variablen, find, Dateideskriptoren und entfernte Operationen.

Shell-Variablen verwenden

Die Bash-Variablen werden beim Aufruf von der Shell gesetzt. Warum sollte ich hostname verwenden wann ich $HOSTNAME verwenden kann, oder warum sollte ich whoami verwenden Wann kann ich $USER verwenden? Bash-Variablen sind sehr schnell und erfordern keine externen Anwendungen.

Dies sind einige häufig verwendete Variablen:

$PATH
$HOME
$USER
$HOSTNAME
$PS1
..
$PS4

Verwenden Sie das echo Befehl zum Erweitern von Variablen. Beispielsweise kann die Shell-Variable $PATH durch Ausführen von:

erweitert werden
$> echo $PATH

[ Jetzt herunterladen:Eine Anleitung für Systemadministratoren zum Bash-Skripting. ]

Verwenden Sie den Suchbefehl

Der find Der Befehl ist wahrscheinlich eines der am häufigsten verwendeten Tools im Linux-Betriebssystem. Es ist äußerst nützlich in interaktiven Shells. Es wird auch in Skripten verwendet. Mit find Ich kann Dateien auflisten, die älter oder neuer als ein bestimmtes Datum sind, sie basierend auf diesem Datum löschen, Berechtigungen von Dateien oder Verzeichnissen ändern und so weiter.

Machen wir uns mit diesem Befehl vertraut.

Um Dateien aufzulisten, die älter als 30 Tage sind, führe ich einfach Folgendes aus:

$> find /tmp -type f -mtime +30

Um Dateien zu löschen, die älter als 30 Tage sind, führen Sie Folgendes aus:

$> find /tmp -type f -mtime +30 -exec rm -rf {} \;

oder

$> find /tmp -type f -mtime +30 -exec rm -rf {} +

Während die obigen Befehle Dateien löschen, die älter als 30 Tage sind, wie geschrieben, verzweigen sie den rm Befehl jedes Mal, wenn sie eine Datei finden. Diese Suche kann effizienter geschrieben werden, indem xargs verwendet wird :

$> find /tmp -name '*.tmp' -exec printf '%s\0' {} \; | xargs -0 rm

Ich kann find verwenden um sha256sum aufzulisten Dateien nur durch Ausführen von:

$> find . -type f -exec sha256sum {} +

Und nun zum Suchen und Entfernen von doppelten .jpg-Dateien:

$> find . -type f -name '*.jpg' -exec sha256sum {} + | sort -uk1,1 

Referenzdateideskriptoren

In der Bash-Shell sind Dateideskriptoren (FDs) wichtig für die Verwaltung der Ein- und Ausgabe von Befehlen. Viele Leute haben Probleme, Dateideskriptoren richtig zu verstehen. Jeder Prozess hat drei Standard-Dateideskriptoren, nämlich:

Code Bedeutung Standort Beschreibung
0 Standardeingabe /dev/stdin Tastatur, Datei oder irgendein Stream
1 Standardausgabe /dev/stdout Monitor, Terminal, Display
2 Standardfehler /dev/stderr Exit-Codes ungleich Null sind normalerweise>FD2, display

Nachdem Sie nun wissen, was die Standard-FDs tun, wollen wir sie in Aktion sehen. Ich beginne damit, ein Verzeichnis mit dem Namen foo zu erstellen , die file1 enthält .

$> ls foo/ bar/
ls: cannot access 'bar/': No such file or directory
foo/:
file1

Die Ausgabe Keine solche Datei oder Verzeichnis geht zu Standard Error (stderr) und wird auch auf dem Bildschirm angezeigt. Ich werde denselben Befehl ausführen, aber dieses Mal verwende ich 2> stderr weglassen:

$> ls foo/ bar/ 2>/dev/null
foo/:
file1

Es ist möglich, die Ausgabe von foo zu senden an die Standardausgabe (stdout) und gleichzeitig an eine Datei senden und stderr ignorieren. Zum Beispiel:

$> { ls foo bar | tee -a ls_out_file ;} 2>/dev/null
foo:
file1

Dann:

$> cat ls_out_file
foo:
file1

Der folgende Befehl sendet stdout an eine Datei und stderr an /dev/null damit der Fehler nicht auf dem Bildschirm angezeigt wird:

$> ls foo/ bar/ >to_stdout 2>/dev/null
$> cat to_stdout
foo/:
file1

Der folgende Befehl sendet stdout und stderr an dieselbe Datei:

$> ls foo/ bar/ >mixed_output 2>&1
$> cat mixed_output
ls: cannot access 'bar/': No such file or directory
foo/:
file1

Das ist im letzten Beispiel passiert, wo stdout und stderr auf dieselbe Datei umgeleitet wurden:

    ls foo/ bar/ >mixed_output 2>&1
             |          |
             |          Redirect stderr to where stdout is sent
             |                                                        
             stdout is sent to mixed_output

Ein weiterer kurzer Trick (> Bash 4.4), um sowohl stdout als auch stderr an dieselbe Datei zu senden, verwendet das kaufmännische Und-Zeichen. Zum Beispiel:

$> ls foo/ bar/ &>mixed_output

Hier ist eine komplexere Umleitung:

exec 3>&1 >write_to_file; echo "Hello World"; exec 1>&3 3>&-

Folgendes passiert:

  • exec 3>&1                      stdout in Dateideskriptor 3 kopieren
  • > write_to_file              Lassen Sie FD 1 in die Datei schreiben
  • Echo "Hello World"     Go to file, weil FD 1 jetzt auf die Datei zeigt
  • exec 1>&3                      Kopiere FD 3 zurück auf 1 (Swap)
  • Drei>&-                       Dateideskriptor drei schließen (wir brauchen ihn nicht mehr)

Oft ist es praktisch, Befehle zu gruppieren und dann die Standardausgabe an eine einzelne Datei zu senden. Zum Beispiel:

$> { ls non_existing_dir; non_existing_command; echo "Hello world"; } 2> to_stderr
Hello world

Wie Sie sehen können, wird nur „Hello world“ auf dem Bildschirm ausgegeben, aber die Ausgabe der fehlgeschlagenen Befehle wird in die Datei to_stderr geschrieben.

Fernoperationen ausführen

Ich verwende Telnet, netcat, Nmap und andere Tools, um zu testen, ob ein Remote-Dienst verfügbar ist und ob ich eine Verbindung zu ihm herstellen kann. Diese Tools sind praktisch, aber sie werden nicht standardmäßig auf allen Systemen installiert.

Glücklicherweise gibt es eine einfache Möglichkeit, eine Verbindung zu testen, ohne externe Tools zu verwenden. Führen Sie Folgendes aus, um festzustellen, ob auf einem Remote-Server ein Web-, Datenbank-, SSH- oder ein anderer Dienst ausgeführt wird:

$> timeout 3 bash -c ‘</dev/tcp/remote_server/remote_port’ || echo “Failed to connect”

Um beispielsweise zu sehen, ob serverA führt den MariaDB-Dienst aus:

$> timeout 3 bash -c ‘</dev/tcp/serverA/3306’ || echo “Failed to connect”

Wenn die Verbindung fehlschlägt, wird Verbindung fehlgeschlagen angezeigt Nachricht wird auf Ihrem Bildschirm angezeigt.

Nehmen Sie serverA an ist hinter einer Firewall/NAT. Ich möchte sehen, ob die Firewall so konfiguriert ist, dass sie eine Datenbankverbindung zu serverA zulässt , aber ich habe noch keinen Datenbankserver installiert. Um einen Datenbankport (oder jeden anderen Port) zu emulieren, kann ich Folgendes verwenden:

[serverA ~]# nc -l 3306

Auf clientA , ausführen:

[clientA ~]# timeout 3 bash -c ‘</dev/tcp/serverA/3306’ || echo “Failed”

Während ich über Remoteverbindungen spreche, wie sieht es mit der Ausführung von Befehlen auf einem Remoteserver über SSH aus? Ich kann den folgenden Befehl verwenden:

$> ssh remotehost <<EOF  # Press the Enter key here
> ls /etc
EOF

Dieser Befehl führt ls /etc aus auf dem entfernten Host.

Ich kann auch ein lokales Skript auf dem Remote-Host ausführen, ohne das Skript auf den Remote-Server kopieren zu müssen. Eine Möglichkeit ist die Eingabe von:

$> ssh remote_host 'bash -s' < local_script

Ein weiteres Beispiel besteht darin, Umgebungsvariablen lokal an den Remote-Server zu übergeben und die Sitzung nach der Ausführung zu beenden.

$> exec ssh remote_host ARG1=FOO ARG2=BAR 'bash -s' <<'EOF'
> printf %s\\n "$ARG1" "$ARG2"
> EOF
Password:
FOO
BAR
Connection to remote_host closed.

Es gibt viele andere komplexe Aktionen, die ich auf dem Remote-Host ausführen kann.

Abschluss

Bash hat sicherlich mehr zu bieten, als ich in diesem zweiteiligen Blogbeitrag behandeln konnte. Ich teile, was ich weiß und womit ich täglich zu tun habe. Die Idee ist, Sie mit einigen Techniken vertraut zu machen, die Ihre Arbeit weniger fehleranfällig und unterhaltsamer machen könnten.

[ Möchten Sie Ihre Fähigkeiten als Systemadministrator testen? Machen Sie noch heute einen Kompetenztest. ]


Linux
  1. Dumme Bash-Tricks:Verlauf, Wiederverwendung von Argumenten, Dateien und Verzeichnissen, Funktionen und mehr

  2. Wie mache ich "head" und "tail" bei einer durch Null getrennten Eingabe in Bash?

  3. Durchführen von atomaren Schreibvorgängen in einer Datei in Bash?

  4. Suchen Sie eine Datei mit den Befehlen Suchen und Suchen in Linux

  5. Linux .htaccess Tipps und Tricks

Älteste Datei finden und löschen, wenn mehr als X Dateien in einem Verzeichnis in Linux vorhanden sind

Nützliche Geany-Plugins, Tipps und Tricks

So verwenden Sie Sed zum Suchen und Ersetzen einer Zeichenfolge in einer Datei

Threads und Dateideskriptoren

Dateien oder Ordner finden und löschen, die älter als x Tage sind

Durchführen von atomaren Schreibvorgängen in einer Datei in Bash