Diskussions- und Newsboard der Linux Interessen Gruppe Suletuxe
allgemeine Kategorie => Allgemeine Diskussionen => Thema von: Sebastian am 07. August 2022, 18:07:11

Titel: Bash Tipps and Tricks
Beitrag von: Sebastian am 07. August 2022, 18:07:11

Ich möchte hier eine kleine Sammlung über nützliche Bash Optionen und eventuell exotische (nicht so bekannte) Techniken anlegen. Jeder ist gerne dazu eingeladen sich mit einzubringen.

Bash History

Eins der ersten Dinge die mir auffiel als ich EndeverOS installiert hatte, war das durch ein Leerzeichen am Anfang der Zeile die Bash History sich nicht temporär für diesen einen Befehl abschalten lies. Das nutze ich ganz gerne für Sensible Befehle die nicht in der History aufgenommen werden sollen. Also im Bash Manual (https://www.gnu.org/software/bash/manual/bash.html#Bash-Variables) nachgeschlagen, und festgestellt das für dieses Verhalten die Bash Variable HISTCONTROL zuständig ist.
Zitat:
HISTCONTROL
A colon-separated list of values controlling how commands are saved on the history list. If the list of values includes ‘ignorespace’, lines which begin with a space character are not saved in the history list. A value of ‘ignoredups’ causes lines which match the previous history entry to not be saved. A value of ‘ignoreboth’ is shorthand for ‘ignorespace’ and ‘ignoredups’. A value of ‘erasedups’ causes all previous lines matching the current line to be removed from the history list before that line is saved. Any value not in the above list is ignored. If HISTCONTROL is unset, or does not include a valid value, all lines read by the shell parser are saved on the history list, subject to the value of HISTIGNORE. The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of HISTCONTROL.


Dadurch habe ich zusätzlich erfahren das es auch einen Wert erasedups für die Variable HISTCONTROL gibt, die dafür sorgt das Dubletten aus der History entfernt werden, und das auch in der .bash_history wo die History Einträge nach der Beendigung der Shell rein geschrieben werden.

Dadurch bin ich für meine ~/.bashrc Datei auf folgenden Eintrag gekommen.


Code:

# Erase duplicate history entries, and do not add commands to the history with a Prefix Space
export HISTCONTROL=erasedups:ignorespace


Dann ein wenig weiter im Handbuch (https://www.gnu.org/software/bash/manual/bash.html#The-Shopt-Builtin) geschmökert und folgende Option gefunden:
Zitat:
histverify
If set, and Readline is being used, the results of history substitution are not immediately passed to the shell parser. Instead, the resulting line is loaded into the Readline editing buffer, allowing further modification.


Das dafür sorgt das Befehle die durch die History Substitution !NR (z.b. !250) nicht sofort ausgeführt werden, sondern erst mal in die Zeile eingefügt werden, damit man den Befehl noch mal kontrollieren kann, bzw. Veränderungen davor vornehmen kann. Zum aktivieren ein weiterer Eintrag in die ~/.bashrc


Code:

# Verify History Command before run
shopt -s histverify


Um jetzt auch die History Substitution auch vernünftig für die letzten Befehle nutzen zu können ohne ständig mit history die Nummern nachschlagen zu müssen, habe ich den Zahlen Eintrag in der History in meinen Promt mit aufgenommen. Mein ganzer Promt sieht dann jetzt so aus:

Promt


Code:

# Set Prompt
PS1='[$((\!-1)) $? \W]\$ '


\! = zeigt den letzten History Eintrag im Promt an.
$((\!-1)) = Da es bei der Ausführung des letzten Befehls ein Versatz um 1 gibt, ziehe ich diesen um eins wieder ab.
$? = Zeigt den letzten Fehler Code des letzten Befehls an. Dadurch lernt man beiläufig exotische Exit Codes seiner Programme kennen, weil man diese sonst normalerweise nicht zu Gesicht bekommt.
\W = Aktuelles Verzeichnis
\$ = Zeigt ob man eine User oder Root Shell grade verwendet.


PS:

@Andreas dein Forum schein Backslashes \\ zu verschlucken selbst in einem Code Tag. Musste die Backslashe hier doppelt Maskieren damit einer stehen blieb. Zumindest bei der Vorschau ist das passiert. Wenn überall gleich noch ein \\ zu sehen ist dann werden welche Verschluckt.

Ein Backslash nach dem gleich Zeichen = \
Doppelte Maskierung nach dem gleich Zeichen = \\

Edit:

Ok anscheint werden die Backslashes nur in der Vorschau aus dem Editor entfernt.

Titel: Re:Bash Tipps and Tricks
Beitrag von: Andreas am 08. August 2022, 04:49:38

Das ist ein Sicherheitsmechanismus der das schnelle Einschleusen von PHP-Code auf den Server verhindert - also Absicht...

LG
Andreas

Titel: Re:Bash Tipps and Tricks
Beitrag von: Sebastian am 09. August 2022, 12:22:17

Befehle als Gruppe zusammen fassen

Eine ich glaube eher seltene aber durchaus sinnvolle Technik um den Output von mehreren Befehle zusammen zu fassen ist indem man diese zu einer Gruppe zusammen fast.

Um es besser zu verdeutlichen hier ein kleines beispiel:


Code:

echo "Dieser String wird in output.txt umgleitet" > output.txt
ls -l >> output.txt
cat foo.txt >> output.txt


Der Output des ersten Befehls wird dabei in die Datei "output.txt umgleitet. Alle weiteren Befehle fügen ihren Output an die Datei "output.txt" an. Soweit so gut, und soweit wahrscheinlich alles bekannt.

Jetzt das gleiche als Kommando Gruppe zusammen gefasst, dabei haben wir zwei Möglichkeiten:

Ausführung in der Aktuellen Shell:

Code:

{ echo "Dieser String wird in output.txt umgleitet"; ls -l; cat foo.txt; } >output.txt


Ausführung in einer Sub Shell:

Code:

( echo "Dieser String wird in output.txt umgleitet"; ls -l; cat foo.txt; ) >output.txt


Beide haben gemein das wir uns ein wenig Tipperei ersparen können. Die gravierende Unterschiede liegen dabei eher, dass wenn der Code in der Aktuellen Shell ausgeführt wird, dies etwas Performanter läuft, da keine extra shell gestartet werden muss.

Zudem falls wir Code verwenden der in einer Subshell Werte in Variablen speichert, muss man bedenken das diese Werte nach Beendigung der Subshell uns nicht mehr zu Verfügung stehen, da das ganze Environment (Umfeld) der Subshell mit gelöscht wird.

Titel: Re:Bash Tipps and Tricks
Beitrag von: Sebastian am 02. September 2022, 18:10:36

Benutzt nicht touch zum Erstellen einer leeren Datei

Zum Erstellen einer neuen leeren Datei, wird häufig das touch Binary missbraucht. Dabei ist der Anwendungszweck von touch ein ganz anderer
Zitat:
touch - change file timestamps


Stattdessen kann man einfach die Output Redirection der eigenen shell verwenden.


Code:

>EMPTY_FILE


Es wird hierbei ein leerer Output Stream in eine Datei geleitet, wodurch diese dann angelegt wird, falls es sie noch nicht geben sollte. Vorteil hierbei, es muss für das Anlegen einer neuen leeren Datei kein neuer Prozess gestartet werden.

Soll die Datei natürlich mit einem bestimmten Zeitstempel angelegt werden, ist wieder touch zu bevorzugen, damit zwei Dinge in einem Aufruf erledigt werden können.

Titel: Re:Bash Tipps and Tricks
Beitrag von: Sebastian am 03. September 2022, 16:16:21

Benutzt type -P statt which

Um zu kontrollieren, ob ein Binary oder Script über die $PATH Variable gefunden werden kann, wird häufig which dafür verwendet. Der Nachteil an which ist, das dies ein eigenständiges Binary ist, und somit wieder ein extra Prozess gestartet werden muss. Zudem gibt es eine sehr kleine Chance, das selbst which nicht installiert ist.

type -P ist hingegen ein Shell Buildin und kann somit direkt von der laufenden Bash shell ausgeführt werden, und brauch somit keinen eigenen Prozess. Die Ausgabe ist dabei die gleiche wie die von which, wenn eine Datei im $PATH gefunden wurde. Wurde keine Datei gefunden, dann wird nichts zurückgeben und ein Exit Code 1


Code:

type: type [-afptP] Name [Name ...]
Display information about command type.

For each NAME, indicate how it would be interpreted if used as a
command name.

Options:
-a   display all locations containing an executable named NAME;
      includes aliases, builtins, and functions, if and only if
      the `-p' option is not also used
-f   suppress shell function lookup
-P   force a PATH search for each NAME, even if it is an alias,
      builtin, or function, and returns the name of the disk file
      that would be executed
-p   returns either the name of the disk file that would be executed,
      or nothing if `type -t NAME' would not return `file'
-t   output a single word which is one of `alias', `keyword',
      `function', `builtin', `file' or `', if NAME is an alias,
      shell reserved word, shell function, shell builtin, disk file,
      or not found, respectively

Arguments:
NAME   Command name to be interpreted.

Exit Status:
Returns success if all of the NAMEs are found; fails if any are not found.


Diskussions- und Newsboard der Linux Interessen Gruppe Suletuxe | Powered by YaBB SE
© 2001-2003, YaBB SE Dev Team. All Rights Reserved.