Bash: Porovnání verzí
m doplněna zmínka o příkazech basename a dirname |
|||
(Není zobrazeno 5 mezilehlých verzí od stejného uživatele.) | |||
Řádek 1: | Řádek 1: | ||
'''Bash''' je shell, tj. příkazový interpret, který je součástí operačního systému GNU. | '''Bash''' je shell, tj. příkazový interpret, který je součástí operačního systému GNU. Ve skriptech v jazyce bash označuje výraz <tt>$0</tt> adresář a jméno skriptu. Pro získání adresáře ze kterého byl skript spuštěn slouží příkaz <tt>dirname $0</tt>, pro získání jména skriptu bez adresáře <tt>basename $0</tt>. | ||
== Ukázky a příklady == | == Ukázky a příklady == | ||
=== Dávkový editor sed === | |||
Odstranění mezer na konci řádků. | |||
<pre> | |||
sed -i -e 's/[[:space:]]*$//' soubor(y) | |||
</pre> | |||
=== Příkazy find, sed, grep, case, echo a cmp === | === Příkazy find, sed, grep, case, echo a cmp === | ||
Řádek 96: | Řádek 103: | ||
</pre> | </pre> | ||
=== Úklid pracovních adresářů (case, if, | === Úklid pracovních adresářů (case, if, find, xargs) === | ||
Skript provádí úklid pracovních adresářů, může být pravidelně spouštěn v cronu (na serveru) nebo při startu systému (na osobním počítači). Soubory a adresářě starší než jeden týden přesouvá do adresáře .null, kde jsou smazány po dvou měsících. | Skript provádí úklid pracovních adresářů, může být pravidelně spouštěn v cronu (na serveru) nebo při startu systému (na osobním počítači). Soubory a adresářě starší než jeden týden přesouvá do adresáře .null, kde jsou smazány po dvou měsících. | ||
Řádek 102: | Řádek 109: | ||
<pre> | <pre> | ||
#!/bin/bash | #!/bin/bash | ||
### BEGIN INIT INFO | |||
# Provides: uklid | |||
# Required-Start: $remote_fs $syslog | |||
# Required-Stop: $remote_fs $syslog | |||
# Default-Start: 2 3 4 5 | |||
# Default-Stop: 0 1 6 | |||
# Short-Description: Uklid pracovniho adresare | |||
# Description: This file should be placed in /etc/init.d | |||
# 1) cp uklid /etc/init.d | |||
# 2) update-rc.d uklid defaults | |||
# | # | ||
# | ### END INIT INFO | ||
# | |||
# | |||
# | # | ||
# | # | ||
case "$1" in | case "$1" in | ||
Řádek 120: | Řádek 132: | ||
NULL=/home/cepek/.null | NULL=/home/cepek/.null | ||
if ! test -d $NULL; then mkdir $NULL; fi | |||
if ! test -d $NULL/`date -I` ; then | |||
mkdir $NULL/`date -I` | |||
fi | |||
WORKDIR="/home/cepek/work" | |||
touch $WORKDIR | |||
for WORK in $WORKDIR | |||
do | do | ||
if ! | if [ "xxx`find $WORK -maxdepth 1 -mtime +6 -print0`xxx" != "xxxxxx" ]; | ||
then | |||
find $WORK -maxdepth 1 -mtime +6 -print0 | xargs -0 mv -v -t $NULL/`date -I`; | |||
fi | fi | ||
done | done | ||
find $NULL -maxdepth 1 -mtime +60 -print0 | xargs -0 rm -rfv | |||
;; | ;; | ||
stop) | stop) | ||
Řádek 171: | Řádek 165: | ||
</pre> | </pre> | ||
=== Porovnání souborů ze dvou adresářů ( find, grep, sed, diff) === | === Porovnání souborů ze dvou adresářů (find, grep, sed, diff) === | ||
Jména prohledávaných adresářů jsou uvedena explicitně, mohou být pochopitelně nahrazena pozičními parametry $1 a $2. Znak % je v příkazu sed použit proto, aby nekolidoval s oddělovačem jmen souborů a adresářů /. | Jména prohledávaných adresářů jsou uvedena explicitně, mohou být pochopitelně nahrazena pozičními parametry $1 a $2. Znak % je v příkazu sed použit proto, aby nekolidoval s oddělovačem jmen souborů a adresářů /. |
Aktuální verze z 29. 11. 2010, 09:03
Bash je shell, tj. příkazový interpret, který je součástí operačního systému GNU. Ve skriptech v jazyce bash označuje výraz $0 adresář a jméno skriptu. Pro získání adresáře ze kterého byl skript spuštěn slouží příkaz dirname $0, pro získání jména skriptu bez adresáře basename $0.
Ukázky a příklady
Dávkový editor sed
Odstranění mezer na konci řádků.
sed -i -e 's/[[:space:]]*$//' soubor(y)
Příkazy find, sed, grep, case, echo a cmp
Bash skript pro porovnání dvou adresářů s ošetřením jmen souborů obsahujících mezery, odfiltrováním skrytých souborů a rotující vrtulkou jako indikátorem průběhu zpracování (ukázka použití příkazu case
).
#!/bin/bash SRC=amonit-2009-04-29 TRG=amonit-CD FILES=$(cd $SRC && find -type f | sed s/\ /?/g | grep -v /\\. ) c=- for i in $FILES do case $c in -) c=\\ ;; \\) c=\| ;; \|) c=/ ;; /) c=- ;; esac echo -en "\b$c" cmp -l $SRC/$i $TRG/$i done
Příkazy for, if, find, grep, md5sum, awk, cmp a sqlite3
Skript prohledá zadné akresáře a vytvoří seznam duplicitní souborů, tj. identických souborů nacházejících se v různých adresářích. Implicitně hledá duplicity v běžném adresáři. Pro všechny nalezené soubory nejprve skript vypočítá jejich kontrolní součty (md5sum
), v databázi sqlite
je agreguje, soubory se stejnými md5 součty porovná příkazem cmp
a vytvoří jejich seznam.
Soubory se jmény obsahujícími mezery a znaky ( a soubory v adresarich cvs
jsou ignorovány.
#!/bin/bash LIST="/tmp/$$-duplicate-files" rm -f $LIST.* if [ "$1" == "" ]; then DIRS=. else DIRS="$1 $2 $3 $4 $5 $6 $7 $8 $9" fi cat <<EOF >$LIST.awk { print "INSERT INTO df VALUES ('" \$1 "', '" \$2 "');" } EOF sqlite3 $LIST.db "CREATE TABLE df (md5 char(32), file text)"; for d in $DIRS do for f in $(find $d -type f | grep -v "\ " | grep -v "(" | grep -v \/CVS\/ ) do md5sum $f | awk -f $LIST.awk | sqlite3 $LIST.db done done cat <<EOF > $LIST.sql DELETE FROM df WHERE md5 IN (SELECT md5 FROM df GROUP BY md5 HAVING count(file) = 1); SELECT a.file, b.file FROM df AS a JOIN df AS b ON a.md5 = b.md5 AND a.file < b.file ORDER BY a.file; EOF cat <<EOF > $LIST.awk {print "if cmp -s " \$1 " " \$2 " ; then echo cmp " \$1 " " \$2 "; fi" } EOF sqlite3 $LIST.db < $LIST.sql | awk -F \| -f $LIST.awk | bash rm -f $LIST.*
Úklid pracovních adresářů (case, if, find, xargs)
Skript provádí úklid pracovních adresářů, může být pravidelně spouštěn v cronu (na serveru) nebo při startu systému (na osobním počítači). Soubory a adresářě starší než jeden týden přesouvá do adresáře .null, kde jsou smazány po dvou měsících.
#!/bin/bash ### BEGIN INIT INFO # Provides: uklid # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Uklid pracovniho adresare # Description: This file should be placed in /etc/init.d # 1) cp uklid /etc/init.d # 2) update-rc.d uklid defaults # ### END INIT INFO # # case "$1" in start) echo "Starting script uklid " # uklid pracovniho adresare # ----------------------------------------------------------- NULL=/home/cepek/.null if ! test -d $NULL; then mkdir $NULL; fi if ! test -d $NULL/`date -I` ; then mkdir $NULL/`date -I` fi WORKDIR="/home/cepek/work" touch $WORKDIR for WORK in $WORKDIR do if [ "xxx`find $WORK -maxdepth 1 -mtime +6 -print0`xxx" != "xxxxxx" ]; then find $WORK -maxdepth 1 -mtime +6 -print0 | xargs -0 mv -v -t $NULL/`date -I`; fi done find $NULL -maxdepth 1 -mtime +60 -print0 | xargs -0 rm -rfv ;; stop) echo "Stopping script uklid" ;; *) echo "Usage: /etc/init.d/uklid {start|stop}" exit 1 ;; esac exit 0
Porovnání souborů ze dvou adresářů (find, grep, sed, diff)
Jména prohledávaných adresářů jsou uvedena explicitně, mohou být pochopitelně nahrazena pozičními parametry $1 a $2. Znak % je v příkazu sed použit proto, aby nekolidoval s oddělovačem jmen souborů a adresářů /.
#!/bin/bash TRG=gama SRC=~/GNU/ro-gama for i in $(find $SRC -type f | grep -v CVS | sed s%$SRC%%) do diff $SRC/$i $TRG/$i done
Výpočet kontrolních součtů pro soubory s mezerami (find, args, md5sum)
Příkazem find vyhledáme v zadaném adresáři všechny soubory a vypočteme pro ně kontrolní součty. Protože soubory mohou obsahovat mezery (a případně další bílé znaky) použijeme parametr -print0, který na výstupu místo konce řádku LF používá znak NULL. Následné zpracování zajistí program xargs.
find adresář -type f -print0 | xargs -0 md5sum