Bash

Z GeoWikiCZ
Přejít na: navigace, hledání

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

Externí odkazy