Admin meets Frontend

… oder was „JavaScript“ und „Shell-Script“ gemeinsam haben.

Zu beginn muss ich zugeben, dass ich bei meinen ersten Skripten auch nicht auf den Sichtbarkeitsbereich von Variablen (Scope) geachtet habe. Wenn man sich jedoch etwas mit Softwareentwicklung auseinandersetze stellt man schnell fest, dass globale Variablen direkt aus der Hölle kommen und nichts im Quelltext zu suchen haben.

Range_of_Variables

Variablen sind zumindest in der Shell und in JavaScript zunächst global, selbst innerhalb von Funktionen und werden erst durch den Zusatz „var“ bzw. „local“ zur lokalen Variable. In vielen anderen Programmiersprachen erkennt man den Scope einer Variable direkt im Zusammenhang, ist z.B. eine Variable innerhalb einer Methode deklariert, so ist diese nur innerhalb dieser Methode verfügbar. Wird die Variable jedoch innerhalb der Klasse deklariert, so ist diese für die ganze Klasse und somit für alle Ihre Methoden verfügbar.

Es folgen ein paar Beispiele, wo der Inhalt (Title der Beiträge) des RSS-Feeds von “planet.ubuntuusers.de” ausgegeben werden soll.

JS-Beispiel: mit globalen Variablen

test-1

Um dies selber zu testen, öffne die Verlinkte Datei im Browser (leere Webseite) und öffne die Entwicklertools (F12), schalte die Ansicht auf “Konsole” und lade die Seite neu. Im Quelltext sind ausschließlich globale Variablen verwendet, jedoch funktioniert dieses Script “leider” wie gewünscht. Das Problem mit globalen Variablen ist, dass man den Quelltext dadurch ggf. schwerer lesen kann und diesen nicht wiederverwenden kann. Wenn man z.B. verschiedene Funkionen als unterschiedlichen Skripten zusammenfügt oder zusammen nutzen möchte, welche jedoch ebenfalls globale Variablen nutzen, dann können da sehr eigenartige Ergebnisse bei herauskommen.

JS-Beispiel: mit lokalen Variablen

test-1_1

test-1_1_2

 

In den DevTools von Chrome kann man jetzt den entsprechenden Variablen-Scope sehen. Jedoch ist der Quellcode noch nicht wirklich wiederverwendbar, da wir das zu lösende Problem (also das laden und parsen einer JSON-Datei) nicht auf eine eigene Abstraktionsschicht gebracht haben.

JS-Beispiel: mit lokalen Variablen und Klassen

test-1_2

In diesem Beispiel wurde nun die Klasse “PlanetUbuntuuserJsonData” erstellt welche wiederum von der Klasse “JsonData” dessen Eigenschaften (Variablen & Methoden) erbt. Leider ist der Quelltext hierbei von zirka 50 auf zirka 80 Zeilen erhört worden und funktioniert dabei z.B. nicht im IE < 10. (siehe Kommentare im Quelltext)

JS-Beispiel: ohne Variablen + jQuery

test-2

Dieses Beispiel benötigt zwar die “jQuery”-Bibliothek, welche jedoch bereits entsprechende Funktionalitäten kapselt. Vergleich man diesen Quellcode mit der Vorherigem Version, kann man schnell erkennen, das entschieden weniger Quellcode deutlich besser zu lesen ist. ;-)

Shell-Beispiel: mit globalen Variablen (test_1.sh)

test-bash

In diesem Beispiel sind wieder sehr viele globale Variablen verwendet und wieder funktioniert das entsprechende Skript “leider” trotzdem. Die Funktion “parse_json()” gibt nicht einmal einen Rückgabewert zurück, dafür teilen sich die beiden Funktionen die Variablen. Und im Grunde könnte man den ganzen Quelltext auch einfach ohne Funktionen untereinander schreiben, dies hätte den selben Effekt.

Shell-Beispiel: mit lokalen Variablen (test_2.sh)

Die entsprechende Ausgabe ist bereits im Vorherigen Bild zu sehen. Bei Shell-Skripten kommt es seltener vor, dass man dessen Funktionalität wirklich wiederverwenden möchte, jedoch ist der Quelltext deutlich besser zu lesen, wenn man entsprechende Rückgabewerte und Übergabeparameter verwendet.

Quellen / Links:
– Shell: Advanced Bash-Scripting Guide
– Shell: Coding-Style-Guide von “Oh My Zsh”
– JS: Sichtbarkeitsbereich (Scope) von Variablen
– JS: Objektattribut

 

I ❤ ~/

Vor einiger Zeit habe ich bereits einen Blog-Post über meine “.dotfiles” geschrieben, jedoch habe ich mich damals mehr auf die Installation beschränkt und habe keine Beispiele gezeigt, so dass man den Vorteil der .dotfiles nur schwer erfassen konnte.

Außerdem benötigt man ggf. nur einige Funktionen oder Dateien um sein System an an seine Bedürfnisse anzupassen. Auf der Webseite GitHub ❤ ~/ gibt es sehr gute .dotfiles Sammlungen, welche man einfach “forken” und anpassen und nutzen kann.

PS: wer sich bisher nicht mit “git” auskennt, sollte sich einmal eines der folgenden interaktiven git-Tutorials anschauen:
try.github.io/
pcottle.github.io/learnGitBranching/
gitreal.codeschool.com/


Beispiele zu meinen .dotfiles:

Navigation:
https://github.com/voku/dotfiles/blob/master/.aliases#L75 easier navigation via aliases

Farben für die Kommandozeile:
https://github.com/voku/dotfiles/blob/master/.aliases#L116color for ping / traceroute / ps / top / ...

difflight & filename auto-completion via zsh

Nützliche Shortcuts: z.B. date_*
https://github.com/voku/dotfiles/blob/master/.aliases#L295
more useful shortcuts

Copy&Past via “getclip” und “putclip”: https://github.com/voku/dotfiles/blob/master/.aliases#L368copy text via "getclip" & putclip

kill & pkill via z-shell: https://github.com/voku/dotfiles/blob/master/.redpill/lib/4_completion.zsh#L122kill & pkill via z-shell

grep & ack: https://github.com/voku/dotfiles/blob/master/.aliases#L242grep & ack

git via z-shell: https://github.com/voku/dotfiles/blob/master/.gitconfiggit via z-shell

“ls”-aliases: https://github.com/voku/dotfiles/blob/master/.aliases#L196optimized "ls"-aliases

vim » Automatisch zur letzten Position springen 
https://github.com/voku/dotfiles/blob/master/.vimrc "vim" » jump to last position

vim » Schell-Suche via “#” "vim" » quick search via "<#>" or "*"

vim » markieren Leerzeichen am Ende der Zeile"vim" » highlight trailing spaces in annoying red

vim » Tabs nutzen
https://github.com/voku/dotfiles/blob/master/.vimrc#L564
vim » NERD Tree via “,” + “-“
https://github.com/voku/dotfiles/blob/master/.vimrc.bundles#L18"vim" » "tabs" & "file-view"

vim » Autovervollständigung via Tabulatur-Taste
https://github.com/voku/dotfiles/blob/master/.vimrc#L755"vim" » tab-completion


Erklärungen zu meinen .dotfiles:

.config_dotfiles

In dieser Datei kann man Einstellungen für meine .dotfiles vornehmen. Wenn du z.B. deinen Standard-User-Namen in der Variable “CONFIG_DEFAULT_USER” hinterlegst, wird diese nicht mehr in der Shell-Prompt angezeigt.

.path

In dieser Datei kannst du Pfade zu deinen Ausführbaren Dateien einfügen, so dass du diese ohne Angabe des Pfades ausführen kannst.

Diese Datei ist nicht im öffentlichen Repository und ist via “.gitignore” aus git verbannt, da es vertrauliche Informationen enthalten kann. z.B.: export PATH=”$HOME/utils:$PATH”

.load

In dieser Datei laden wir weitere optionale Einstellungen, welche ggf. gar nicht installiert und somit auch nicht geladen werden müssen.

.colors

Hier definieren wir einige Farben, welche dann in den folgenden Dateien verwendet werden können. z.B.: COLOR_BLACK=\e[0;30m

.exports

Variablen in Shell-Scriptes verhalten sich so ähnlich wie in JavaScript. Variablen sind Standardmäßig “global”, dass heißt selbst Variable innerhalb einer Funktion sind anschließend auch außerhalb der Funktion verfügbar. Daher verwenden wir “local” innerhalb von Funktionen, für Variablen welche nur innerhalb der Funktion zur Verfügung steht sollen. Außerdem können wir Variablen via “export” exportieren, so dass diese nicht nur zur Ausführungszeit, sondern anschließend ebenfalls allen Kindprozessen als Umgebungsvariable zur Verfügung stehen.

.icons

Wie die Farben werden auch die entsprechenden Icons exportiert, so dass wir diese anschließend in Funktionen etc. nutzen können.

.aliases

In dieser Datei werden Abkürzungen für komplexe Befehle oder / und Fallbacks definiert, welche anschließend als Befehl ausgeführt werden.

z.B.:
alias starwars=’telnet towel.blinkenlights.nl’
alias sgrep=’grep -R -n -H -C 5 –exclude-dir={.git,.svn,CVS}’

.bash_complete // completion.zsh

Auch wenn die “Z-Shell” (zsh) bessere Tabcompletion bietet, kann man auch in der “Bash” einige  Tabcompletion-Features nutzen.

z.B.:


apt- [Tabulator]
apt-g [Tabulator]
apt-get [Tabulator]
apt-get i [Tabulator]
apt-get install [Tabulator] [Tabulator]
apt-get install apa [Tabulator]

.functions

Hier habe ich einige praktische Funktionen gesammelt, welche ich öfters nutze und nicht als Plugin auslagern möchte.

z.B.:
lman() -> “Open the manual page for the last command you executed”
netstat_free_local_port() -> “get one free tcp-port”
iptablesBlockIP() -> “block a IP via ‘iptables'”

Überlegungen: In der “normalen” Programmierung nutzt man lowerCamelCase für normale Variablen / Funktionen und Methoden, jedoch sind eigentlich alle Funktionen in der Shell lowercase z.B.: whoami, updatedb, killall. Ich mich dafür entschieden mich bei neuen Funktionen und Aliases an einem Original-Befehl zu orientieren, so dass man diese nicht neu lernen muss, sondern diese via [Tabulator] nutzen kann.

.extra

Auch diese Datei ist nicht im öffentlichen Repository und ist via “.gitignore” aus git verbannt, da es vertrauliche Informationen enthalten kann. Hier kann man alle zuvor gesetzten Variablen, Einstellungen, Funktionen überschreiben oder ergänzen.

ShellShock – Sicherheitsproblem bei der Unix-Shell $(bash)

Alle alten Version der Unix-Shell “bash” enthalten eine kritische Sicherheitslücke (CVE-2014-6271), so dass man Befehle z.B. über CGI-Skripte oder via DHCP ausführen kann.  Ggf. benötigt nun dein Handy (z.B. CyanogenMod), dein Router oder deinen Mac / Linux / BSD und so weiter Software-Updates.

Teste dein System:

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

vulnerable
this is a test

Nachdem man die aktuellen Updates eingespielt hat (z.B. via aptitude) dann sollte die Ausgabe folgendermaßen aussehen.

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

bash: warning: x: ignoring function definition attempt bash: error importing function definition for `x’ this is a test

Technische Erklärung:

(http://seclists.org/oss-sec/2014/q3/650)
Das Problem ist, dass das man zwischen unterschiedlichen Bash-Instanzen Variablen und Funktionen teilen kann.

export foo='() { echo "bar" ; }'
bash -c 'foo'

Jede neue Bash-Instanz wird nun beim Start die Funktion “foo”  registrieren, so dass man diese Ausführen kann. Wenn man nun jedoch eine Funktion exportiert, führt die Bash den nächsten Befehl ebenfalls aus, da der String der “() {” nicht korrekt geparst wird. Damit können wir nun Befehle ausführen, indem wir bestimmte Strings (Funktionsdefinitionen) an z.B. ein CGI-Skript übergeben.

Links:

http://www.heise.de/newsticker/meldung/Bash-Luecke-ShellShock-ist-noch-nicht-ausgestanden-2403607.html

http://www.heise.de/newsticker/meldung/ShellShock-Standard-Unix-Shell-Bash-erlaubt-das-Ausfuehren-von-Schadcode-2403305.html

http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-025

 

Kurztipp: lokalen offenen Port finden (bash)

Habe soeben folgende Funktionen zu meinen dotfiles hinzugefügt, um einen freien lokalen Port zu finden. Diese werden wiederum verwendet, um z.B. die “phpserver“-Funktion auszuführen.

# -------------------------------------------------------------------
# netstat_used_local_ports: get used tcp-ports
netstat_used_local_ports()
{
  netstat -atn | awk '{printf "%s\n%s\n", $4, $4}' | grep -oE '[0-9]*$' | sort -n | uniq
}

# -------------------------------------------------------------------
# netstat_free_local_port: get one free tcp-port
netstat_free_local_port()
{
  read lowerPort upperPort < /proc/sys/net/ipv4/ip_local_port_range
 
  # create a local array of used ports 
  local all_used_ports=($(netstat_used_local_ports))

  for port in $(seq $lowerPort $upperPort); do
    for used_port in "${all_used_ports[@]}"; do
      if [ $used_port -eq $port ]; then
        continue
      else
        echo $port
        return 0
      fi
    done
  done 
}

 

Web Development mit Linux (Video)

Im folgenden Video zeige ich kurz (~ 5 min.) wie meine Toolchain im Live-Betrieb aussieht, dabei nutze ich unter anderem Sublime Text, PHP, Twig, Grunt, Sass, Compass, LiveReload und ein paar Funktionen aus den “dofiles” (z.B. phpserver).

 

Wer den Beispiel-Code aus dem Video selber ausprobieren möchte, hier die Zusammenfassung:

sudo apt-get install git

cd ~
git clone https://github.com/voku/dotfiles/
cd dotfiles/
./firstInstall.sh
./bootstrap.sh
cd ~
vim ~/.extra #1

cd ~
mkdir Projects/
git clone https://github.com/voku/twig-wrapper-example/
cd twig-wrapper-example/
npm install
grunt watch

cd ~/Projects/twig-wrapper-example/
phpserver

#1 füge deine persönlichen Git-Einstellungen hier hinzu

 

Wer mehr Infos oder Erklärungen zu den hier verwendeten Tools haben möchte, sollte sich einmal folgende Videos anschauen: suckup.de/howto/html/moderner-build-development-workflow-via-bower-grunt-yeoman/

 

Kurztipp: mysqldump + Views

Problem: “DEFINER”

Jeder MySQL-Dump welcher mit dem Befehl “mysqldump” erstellt wird beinhalte die Einstellung zum “DEFINER”.

z.B.: DEFINER=`root`@`localhost` SQL SECURITY DEFINER

Dies bedeutet, dass man diesen SQL-Dump nicht einfach z.B. auf dem Ziel-Server nutzen kann, da die Applikation wahrscheinlich / hoffentlich keinen Root-Zugriff auf die Datenbank hat.

Lösung: via “grep”

Als schnelle Lösung für diese Problem entferne ich einfach den entsprechenden DEFINER-Eintrag.

mysqldump -u your_user --skip-comments --skip-opt --complete-insert --databases your_db | grep -v 'SQL SECURITY DEFINER' > ~/your_dump.sql

http://gist.suckup.de/tpl_default.php?pid=1#sec_fb936cf7878c32a5f0b0

Tipp im Tipp

Falls man mit Windows arbeiten muss, empfehle ich die Git-Bash (MinGW + GIT) zu installieren und das “mysql/bin” Verzeichnis im Windows PATH (System -> Erweiterte Systemeinstellungen -> Umgebungsvariablen) einzutragen. So kann man den oben genannten Befehl (und vieles mehr) auch unter Windows nutzen!

 

Links & Quellen:

– http://dev.mysql.com/doc/refman/5.1/de/create-view.html
– http://www.sitepoint.com/mysql-views/
– http://www.mingw.org/
– http://msysgit.github.io/

Prompt › Bash

Ich habe schon vor einiger Zeit über die “.bashrc” berichtet und hier die Installation meiner dotfiles [~/.*] vorgestellt.

Heute möchte ich an einigen Bildern zeigen wie die Bash aussieht nachdem man die bereits erwähnten dotfiles installiert und wie man diese nach seinen Wünschen anpasst.

bash_prompt

1.) der Code

.bashrc: Dies ist die Konfigurationsdatei der Bash, diese wird bei jedem Aufruf einer interaktiven Shell ausgeführt. In meiner .bashrc stehen zunächst einmal ein paar Informationen, wovon ich hier nur die entsprechenden Links nennen möchte, welche man sich einmal anschauen sollte:

– http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/
– www.commandlinefu.com/commands/browse/sort-by-votes
– https://twitter.com/climagic

.bash_profile: Diese Datei hat die selbe Aufgabe wie die .bashrc, wird jedoch “eigentlich” nur für Login-Shells aufgerufen. In diesem Fall wird die Datei jedoch auch für interaktive Shells verwende, da wir diese in der .bashrc inkludiert haben.

for file in ~/.{path,colors,icons,exports,aliases,bash_complete,functions,extra,bash_prompt}; 
do [ -r "$file" ] && [ -f "$file" ] && source"$file" 
done 
unset file

In dieser Datei werden wiederum andere Shell-Konfigurationen geladen (siehe vorheriges Code-Beispiel), welche auch von anderen Shells (z.B.: der zsh) genutzt werden können.

Desweiteren werden einige Einstellungen in einer zweiten for-Schleife ausgeführt. Andere Einstellungen sind näher beschrieben bzw. nur für nicht root-User geeignet und werden daher einzeln ausgeführt.

 .bash_prompt: Wie wir im vorherigem Code-Ausschnitt sehen konnten, wird diese Datei zum Schluss geladen, so dass wir zuvor definierte Funktionen und Variablen verwenden können.

# Local or SSH session?
local remote=""
[ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ] && remote=1

Wir prüfen, ob es sich hier um ein lokales Terminal oder um eine SSH Verbindung handelt, so dass wir den Hostnamen nur anzeigen, wenn dieser auch benötigt wird.

# set the user-color
local user_color=$COLOR_LIGHT_GREEN           # user's color
[ $UID -eq "0" ] && user_color=$COLOR_RED     # root's color

Root-User bekommen in der Prompt einen Roten-Usernamen angezeigt.

PS: die User-ID (UID) ist in der passwd zu finden: “cat /etc/passwd”

# set the user
local user="\u"

Die Zeichenkette “\u” wird beim Aufruf der Bash-Prompt in den entsprechenden Usernamen umgewandelt.

PS: hier gibt es eine Übersicht über weiter Zeichenketten, welche von der Bash-Prompt verarbeitet werden können z.B. die Uhrzeit

# set the hostname inside SSH session
local host=""
[ -n "$remote" ] && host="\[$COLOR_LIGHT_GREEN\]${ICON_FOR_AT}\h"

Wie bereits erwähnt zeigen wir den Hostnamen (“\h”) nur an, wenn es sich um eine Remote-Verbindung handelt.

if [[ -n $remote ]] && [[ $COLORTERM = gnome-* && $TERM = xterm ]] && infocmp gnome-256color >/dev/null 2>&1; then
  export TERM='gnome-256color'
elif infocmp xterm-256color >/dev/null 2>&1; then
  export TERM='xterm-256color'
fi

256 Farben in der lokalen Shell verwenden.

# INFO:   Text (commands) inside \[...\] does not impact line length calculation which fixes stange bug when looking through the history
#         $? is a status of last command, should be processed every time prompt prints

Da der Bash-Prompt bestemmte Zeichen nicht mag und wir davon einige in der bereits inkludierten “.colors“-Datei verwendet haben, müssen wir diese Variablen nun hier escapen.

# Format prompt
export PS1="\`if [ \$? -eq 0 ]; then echo -e \[\$COLOR_GREEN\]\${ICON_FOR_TRUE}; else echo -e \[\$COLOR_RED\]\${ICON_FOR_FALSE}; fi\` \[$user_color\]${user}${host}\[$user_color\]:\[$COLOR_LIGHT_BLUE\]\w\[$COLOR_LIGHT_RED\]${ICON_FOR_ARROW_RIGHT}\$(__git_branch)\$(__svn_branch)\$(__git_dirty)\[$COLOR_NO_COLOUR\] "

Der Prompt wird in der Variable PS1 (“echo $PS1″) gespeichert und nach jedem Befehl auf der Kommandozeile neu aufgerufen / ausgeführt, daher rufen wir in der Variable wiederum Funktionen auf, so dass diese Funktionen ebenfalls erneut ausgeführt werden.

PS: “$?” muss als erstes ausgeführt werden, da dieser Befehl den Rückgabewert des letzten Kommandos zurückliefert

2.) Beispiele

bash_prompt_false

– Root-User wird rot gekennzeichnet

– “” anzeigen, wenn der letzte Befehl nicht korrekte funktioniert hat

 

bash_prompt_remote

– Anzeigen des Hostnamens nur bei Remoteverbindungen

– Repository-Branch (git, svn) anzeigen

–  Repository-Status anzeigen (! anfügen, wenn etwas nicht eingecheckt ist)

 

Links & Quellen:

http://wiki.ubuntuusers.de/Bash/Prompt
https://wiki.archlinux.de/title/Bash-Prompt_anpassen
http://ezprompt.net/

CSS > SCSS > CSS

Neue Webseiten werden heutzutage oft via SASS erstellt, aber was macht man mit alten Projekten? Kann man auch hier SASS einsetzten? – Ja! Das schöne an “SCSS”-Dateien ist das diese 100% mit CSS kompatibel sind, so dass man die entsprechende Dateiendung umbenennen kann und neue / kleine Anpassungen in der SASS-Syntax schreiben kann. Wer jedoch eine ganze CSS-Datei auf den SCSS-Style anpassen möchte kann z.B. den “sass-convert”-Befehl auf der Kommandozeile verwenden.


See the Pen tqJvn by Lars Moelleken (@voku) on CodePen.

CSS > SCSS

Mit dem folgendem Befehl kann man die CSS-Datei in eine SCSS-Datei umwandeln lassen.

sass-convert --from css --to scss test.css test.scss

See the Pen Arxuv by Lars Moelleken (@voku) on CodePen.

Es folgt eine kleine manuelle Optimierung, dabei gilt: Umso besser die ursprüngliche CSS-Datei aufgebaut war, desto besser kann diese konvertiert werden.


See the Pen eFdlJ by Lars Moelleken (@voku) on CodePen.

SCSS > CSS

Nun erstellen wir aus der neuen SCSS-Datei wieder eine CSS-Datei + Sourcemap

scss  --sourcemap --line-comments --style expanded test.scss test_new.css

See the Pen pErjB by Lars Moelleken (@voku) on CodePen.

PS: mithilfe der Source Map kann Chrome automatisch die entsprechenden Code-Stellen in der entsprechenden SCSS-Datei  anzeigen :)

 

Links:
http://sassmeister.com/
http://css-tricks.com/sass-style-guide/

Quellen:
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#output_style

grep, ack, find, locate, sed, diff, wc …

An dieser Stelle wollte ich einmal notieren wie ich in der täglichen Arbeit mit z.B. “grep” oder “find” etc. umgehe, um möglichst schnell in Verzeichnissen und Dateien zu suchen oder Text zu ersetzten.

Ich werde hier nicht alle Möglichkeiten der entsprechenden Befehle nennen können, daher beschränke ich mich auf das, was ich wirklich verwende. Falls du dich weiter in der Thematik einlesen möchtest, empfehle ich gerne den “man”-Befehl oder wie andere es ausdrücken RTFM!

Falls dir die Begriffe tail, cat, less nicht viel sagen, dann klick hier!!!

 

grep: 

global regular expression print -> durchsucht Dateien und Verzeichnisse via RegEx bzw. nach Strings

Kurzform Langform Beschreibung
-H
--with-filename
gibt den Dateinamen vor jedem Treffer aus.
-i
--ignore-case
unterscheide nicht zwischen Groß- und Kleinschreibung.
-n
--line-number
gibt die Zeilennummer vor jedem Treffer aus.
-R
-r
--recursive
liest alle Dateien unter jedem Verzeichnis rekursiv.
-v
--invert-match
Invertiert die Suche und liefert alle Zeilen die nicht auf das gesuchte Muster passen.

z.B.:

grep -rHn test ~/php/

-> sucht im Verzeichnis “php”, welches sich wiederum im Home-Verzeichnis [~] befindet nach dem String “test”

PS: hier der selbe Befehl, jedoch eingeschränkt auf php-Dateien

grep -Hn test ~/php/**/*.php

Info: wenn man “git” im Einsatz hat, sollte man “git grep” verwenden ;)

 

ack:

Ack hat die selbe Aufgabe wie “grep” ist jedoch auf Entwickler zugeschnitten, so sucht “ack” im Standardmäßig rekursiv, ignoriert Binärdaten und Verzeichnisse von Versionkontrollsystemen (.svn, .git, etc.)

PS: unter Debian / Ubuntu findet man das entsprechende Paket unter “ack-grep”

 

find:

ist bei der Suche nach Dateien behilflich (“Alles ist eine Datei”)

Suchkriterien für find
Kriterium Beschreibung
-name Datei
Es wird nach Dateien mit dem Namen “Datei” gesucht. Sollen bei der Suche Platzhalter Verwendung finden, so muss der ganze Ausdruck in Anführungszeichen gestellt werden, zum Beispiel

-name "*.txt"
-iname Datei
Es wird nach Dateien mit dem Namen “Datei” – ohne Beachtung der Groß und Kleinschreibung – gesucht.
-type f
Es wird nur nach regulären Dateien gesucht.
-type d
Es wird nur nach Verzeichnissen gesucht.
find -size +10M -20M -exec ls -lah {} \;

-> sucht alle Dateien welche eine Dateigröße zwischen 10 – 20 MB haben und zeigt diese an

WARNING: der “exec”-Parameter kann auch für jeden anderen Befehl auf die Ergebnismenge von “find” ausführen, dabei sollte man jedoch bei dem “rm”-Befehl besonders vorsichtig sein. Und ggf. kann man sich safe-rm anschauen. ;)

PS: hier sind noch ein paar Beispiel

 

locate:

“sudo updatedb” nicht vergessen und schon kann man sehr schnell nach Dateien suchen, da die Dateien nicht im Filesystem, sondern in einer Datenbank (updatedb) gesucht werden.

z.B.:

locate Download | grep home

 

sed:

Es handelt sich hier um einen “nicht-interaktiver Texteditor” was eigentlich nur bedeutet, dass man damit String verarbeite kann. Zum Bespiel kann man ein bestimmtes Wort in einer Datei durch ein anderes ersetzten.

https://github.com/voku/dotfiles/blob/master/.functions

# WARNING -> replace: changes multiple files at once
replace()
{
  if [ $3 ]; then
    find $1 -type f -exec sed -i 's/$2/$3/g' {} \;
  else
    echo "Missing argument"
  fi
}
replace *.php alt neu

-> dieser Befehl such im aktuellen (+ Unterverzeichnisse) nach Dateien, welche auf “.php” enden und ersetzt darin “alt” gegen “neu”

PS: hier findet man ein paar nützliche Beispiele

Dabei ist besonders praktisch, dass man diese Funktionalität auch im “vim” verwenden kann indem man z.B. folgendes eingibt …

 :%s/alt/neu/g

 

diff:

Wie der Name schon vermuten lässt, kann man hiermit Dateien vergleichen. z.B.:

diff -u --ignore-all-space -r old/ new/

-> vergleicht alle Dateien rekursiv (-r) vom Verzeichnis “old/” und “new/” und ignoriert dabei Änderungen vom Leerräumen z.B. Leerzeichen oder Zeilenumbrüche (\r <-> \r\n)

Info: wenn man “git” im Einsatz hat, sollte man “git diff” verwenden ;)

 

wc:

word count kann Wörtern, Zeichen und Bytes (man ahnt es bereits) zählen. z.B.:

cat /proc/cpuinfo | grep processor | wc -l

-> zählt die Anzahl der CPU-Kerne

 

Quellen:
http://beyondgrep.com/ – ack
http://wiki.ubuntuusers.de/grep
http://wiki.ubuntuusers.de/find
http://wiki.ubuntuusers.de/locate
http://wiki.ubuntuusers.de/wc
http://suckup.de/linux/find-linux/
http://suckup.de/linux/streameditor-sed/

Kurztipp: RegEx für die Paketsuche

Habe soeben einen älteren Blog-Post aktualisiert und einen kleinen Tipp hinzugefügt, welchen ich hier an zwei Beispielen zeigen möchte: suckup.de/linux/ubuntu/aptitude-dpkg/

sudo aptitude search "^php5-[a-cA-C]+"

-> sucht alle Pakete welche mit “php5-” anfangen und darauf “a”, “b oder “c” in beliebiger Häufigkeit folgen

sudo aptitude search "(^bash|^git).*completion"

-> sucht Pakete welche entweder mit “bash” oder mit “git” anfangen gefolgt von beliebigen (auch beliebige Anzahl) von Zeichen, gefolgt von dem String “completion”

Die RegEx-Funktionalität funktioniert sowohl bei “apt-cache”, “apt-get” als auch bei “aptitude” und auch bei anderen Befehlen wie z.B.: “remove”, “install”, “search”, “purge” etc. Bei meinen Tests hat dies jedoch mit “aptitude” am besten funktioniert, da hier nur nach den Paketnamen gesucht wird, falls man jedoch nicht genau weiß wonach man eigentlich sucht, dann sollte man es wohl mit “apt-cache” versuchen.

PS: wer sich RegEx noch nicht angeschaut hat, der sollte auch mal die Links in den Quellen anklicken, da man dies z.B. in so gut wie jeder Programmiersprache, in der Shell oder ansatzweise selbst bei der Google-Suche nutzen kann. Wer mehr über Tricks in der Google-Suche erfahren möchte, klickt hier! ;)

Quellen:
https://www.debian.org/doc/manuals/debian-reference/ch02.de.html#_browsing_with_the_regex_matching
http://regex101.com/
http://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck