Na każdej platformie grep działa troszkę inaczej a Perl nie ;). Dlatego czasem lepiej użyć perla w skrypcie bash-a czy Korn Shella niż korzystać z grep-a. Przykład poniżej jak łatwo można szukać:
perl -ane '{ print $1 if ( /-sn(\w+)/) }'
Na każdej platformie grep działa troszkę inaczej a Perl nie ;). Dlatego czasem lepiej użyć perla w skrypcie bash-a czy Korn Shella niż korzystać z grep-a. Przykład poniżej jak łatwo można szukać:
perl -ane '{ print $1 if ( /-sn(\w+)/) }'
Porządkowałem dzisiaj backupy, strony itp i postanowiłem zrobić backupy razem z datami (czegoś 😉 ),
root@server:/export/backups/remote# find . -mindepth 1 -maxdepth 1 | ls -l | grep -v "total" | while read A A A A A DATE A DIRECTORY; do echo "backuping $DIRECTORY"; tar -zcf ${DIRECTORY}_$(echo $DATE | sed "s/-//g" ).tgz ${DIRECTORY}; done
A jakie daty wpisaliśmy do polecenia powyżej? Sam zobacz:
root@server:/export/backups/remote# stat www.linuxexpert.pl File: `www.linuxexpert.pl' Size: 4096 Blocks: 8 IO Block: 4096 directory Device: fc0dh/64525d Inode: 134830 Links: 21 Access: (0755/drwxr-xr-x) Uid: (65534/ nobody) Gid: (65534/ nogroup) Access: 2012-04-09 19:24:34.468008017 +0200 Modify: 2007-12-15 00:00:00.000000000 +0100 Change: 2012-01-06 15:52:53.595694724 +0100
Czyli datę ostatniej modyfikacji katalogu.
Nauczyłem się przydatnej sztuczki, czyli zamiany tekstu w pliku z linii poleceń:
perl -pi -e 's/127.0.0.1.*\n/127.0.0.1\tlocalhost #server\n/g' /tmp/hosts2
Czego się nauczyłem dzisiaj? Czegoś superowego:
root@server:/etc/apcupsd# false | cat; echo $? ${PIPESTATUS[0]} 0 1
Programować można nie tylko w konsoli, mamy także możliwość pisania skryptów współpracujących z KDE (KDailog) albo z Gnome (Zenity). Linki:
Piszę mały programik to analizy stanów serwerów więc potrzebowałem wykonać analizę w linii poleceń, jak widać poniżej, analizuję wynik polecenia ps zapisanego w pliku:
cat ps | perl -ane 'if ($_ =~ m/(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)\s*$/) {print "$1;$2;$3;$4;$5;$6;$7;$8;\n" } ;' | sed -e "s/\s*;$/;/g"
Prędzej czy później każdy administrator stara się optymalizować swoją pracę przez pisanie skryptów automatyzujących jego pracę. Cześć skryptów zapewnie będzie wykonywała zdalne polecenia przez ssh (nie wszędzie można instalować własne oprogramowanie, nie wszędzie jest Bash). Jeżeli pracujemy w środowisku z wieloma administratorami wypadałoby też sprawdzać w skryptach, czy mamy połączenie do zdalnych systemów.
Jak to można zrobić?
Najprościej użyć kodu błędu ostatniego polecenia ;). W skryptach przeważnie też nie należy pytać o hasło do zdalnej maszyny ;).
user@ubuntu:~$ ssh -o PasswordAuthentication=no root@192.168.1.12 "date" Thu Jul 29 02:04:21 CDT 2011
user@ubuntu:~$ ssh -o PasswordAuthentication=no root@192.168.1.12 "date" > /dev/null 2>&1; echo $? 0
user@ubuntu:~$ ssh -o PasswordAuthentication=no root@192.168.1.12 "date2" > /dev/null 2>&1; echo $? 127
user@ubuntu:~$ ssh -o PasswordAuthentication=no root@alamakota "date2" > /dev/null 2>&1; echo $? 255
W skryptach często dokonuje się przekierowania jakiegoś strumenia danych do plików. Standardowo robiłem to zawsze na zasadzie:
blablabla >> $FILENAME
Pytanie tylko co będzie, gdy w nazwie pliku „$FILENAME” będzie spacja? Skrypt zapisze dane w innym pliku! Tak więc wszystkie nazwy plików powinny być prezentowane w skryptach następująco:
blabla >> "$FILENAME"
Czasem w prostych skryptach warto nadać zmiennym wartość domyślną. W moim przypadku chodzi głównie o nazwy plików konfiguracyjnych, które są ściśle określone ale też można podać opcjonalnie inne pliki. Można to zrobić na dwa sposoby, jeden to oczywiście walka z if i else ale drugi jest bardziej przyjemny.
W przypadku bardzo prostych skryptów mozna użyć zmiennej $1:
LIST_OF_SERVERS=${1:-"servers_list.txt"};
Albo bardziej rozbudowany:
LIST_OF_SERVERS=${LIST_OF_SERVERS:-"servers_list.txt"};
Drobne wyjaśnienie:
Zmienne można zapisywać w dwa sposoby: jako $ + NAZWA_ZMIENNEJ (bardzo to ogranicza wszystkie zabawy z zmienną) oraz jako $ { NAZWA_ZMIENNEJ}. W drugim przypadku możemy używać większej ilości operacji, jak tutaj podstawiania wartości domyślnej.
Cóż, dopadła mnie potrzeba nauczenia się obcinania ciągów znaków w Bash-u (by dobrze operować nazwami plików i hostów). Tak więc dzisiaj nauczyłem się jak obcinać ciągi znaków od początku jak i od końca w dwa sposoby: do pierwszego wystąpienia wzorca oraz do ostatniego wystąpienia wzorca.
Czytaj dalej Bash: Manipulanie ciągami znaków cz.1 – obcinanie