Sziasztok, egy kis segítséget szeretnék kérni van egy backup scriptem és hibásan csomagolja a fájlokat, mar többször átnéztem de nem találom a hibát, csinál egy xy.gz csomagot de a tartalma mar nem elérhető.
#!/bin/bash
# Shell script to backup MySql database and clients websites
# Database credentials. Use a DB user with full read access or use the root user
ispUSER="root" # DB user
ispPASS="---yourpass---" # user's password
ispHOST="localhost" # Hostname
CURDIR="$(pwd)"
# Variables with full path to binaries
MYSQL="$(which mysql)"
MYSQLDUMP="$(which mysqldump)"
CHOWN="$(which chown)"
CHMOD="$(which chmod)"
GZIP="$(which gzip)"
TAR="$(which tar)"
# Your Server's Main Backup Directory
DEST="/var/backup"
# Sites (ONLY) backup directory in your Main Backup Directory
SITES="$DEST/sites"
# Variables for Dates in yymmdd format
TODAY=`date +%Y%0m%0d`
YESTERDAY=`date -d '1 day ago' +%Y%0m%0d`
BACK2=`date -d '2 day ago' +%Y%0m%0d`
BACK3=`date -d '3 day ago' +%Y%0m%0d`
BACK22=`date -d '22 day ago' +%Y%0m%0d`
[ ! -d $SITES ] && mkdir -p $SITES || :
# Give Only root access to backups in this scripts folders
$CHOWN 0.0 -R $SITES
$CHMOD 0600 $SITES
# --------------------------------------------------------------------------
# Remove previous (current) backups of the client directory
# The backups are in the form :
# *BU*gz
# -------- CAUTION ---------
# Do not store any other file in this form in the clients directory
# --------------------------------------------------------------------------
echo "-------------------------------------------------------------"
QRY="use dbispconfig; SELECT web_domain.system_user, web_domain.system_group, \
web_domain.document_root, web_domain.domain FROM web_domain WHERE \
web_domain.type!='alias' AND web_domain.system_user IS NOT NULL AND (LENGTH(web_domain.redirect_path)<5 OR web_domain.redirect_path IS NULL) ;"
echo $QRY | mysql -u $ispUSER -h $ispHOST -p$ispPASS | while read -r line
do # ${col[0]}=domain user / folder name / system user, ${col[1]}=clientID / system group ,
while read -a col # ${col[2]}=path to website, ${col[3]}= domain name
do
echo " CLEANING OLD BACKUPS in ${col[2]} folder "
for delfile in ${col[2]}/*BU*gz ;
do [ -f $delfile ] && rm $delfile;
done
done
done
# --------------------------------------------------------------------------
# Remove anything that is 22 days old and have the form :
# *[date 22 days old]*gz
# from server's $SITES directory
# --------------------------------------------------------------------------
echo "-------------------------------------------------------------"
echo " CLEANING OLD BACKUPS in SITES folder "
for delfile in $SITES/*$BACK22*gz ;
do [ -f $delfile ] && rm $delfile;
done
echo "-------------------------------------------------------------"
echo " "
echo " "
# --------------------------------------------------------------------------
# For each client, backup his database in his website folder
# For client with multiple sites backup all dbs in his first site
# Furthermore copy today's backup in the server's $SITES directory
# Remove the backup that is older than 3 days from server's $SITES directory
# Keep the last 3 Sundays
# --------------------------------------------------------------------------
QRY="use dbispconfig; SELECT web_database.database_name , web_database.database_user ,\
min(web_domain.system_user) as muser, web_domain.system_group, min(web_domain.document_root) as mpath, \
web_domain.domain FROM web_database, web_domain WHERE web_database.sys_userid=web_domain.sys_userid \
AND web_database.sys_groupid=web_domain.sys_groupid AND web_domain.type='vhost' \
AND web_domain.system_user IS NOT NULL AND (LENGTH(web_domain.redirect_path)<5 OR web_domain.redirect_path IS NULL) \
GROUP BY web_database.database_name , web_database.database_user, web_domain.system_group;"
echo $QRY | mysql -u $ispUSER -h $ispHOST -p$ispPASS | while read -r line
do # ${col[0]} = dbname, ${col[1]}=dbuser , ${col[2]}=domain user / folder name / system user,
while read -a col #${col[3]}=clientID / system group , ${col[4]}=path to website
do
echo " DB: "${col[0]}
echo "-------------------------------------------------------------"
echo "Backing Up DB:" ${col[0]} "in :" ${col[4]}/${col[0]}BU.gz
$MYSQLDUMP -u $ispUSER -h $ispHOST -p$ispPASS -c --add-drop-table --add-locks \
--all --quick --lock-tables ${col[0]} | $GZIP -9 > ${col[4]}/${col[0]}BU.gz
cp ${col[4]}/${col[0]}BU.gz $SITES/${col[0]}.$TODAY.gz
if [ `date -d '3 day ago' +%u` -ne 7 ] # if 3 days ago is not Sunday
then #remove the backup
[ -f $SITES/${col[0]}.$BACK3.gz ] && rm $SITES/${col[0]}.$BACK3.gz
fi
$CHOWN ${col[2]}:${col[3]} ${col[4]}/${col[0]}BU.gz
$CHMOD 0660 ${col[4]}/${col[0]}BU.gz
echo "-------------------------------------------------------------"
echo " "
done
done
# --------------------------------------------------------------------------
# For each client, backup his sites in his website folder
# Furthermore copy today's backup in the server's $SITES directory
# Remove the backup that is older than 3 days from server's $SITES diriectory
# Keep the last 3 Sundays
# --------------------------------------------------------------------------
QRY="use dbispconfig; SELECT web_domain.system_user, web_domain.system_group,\
web_domain.document_root, web_domain.domain FROM web_domain WHERE \
web_domain.type!='alias' AND web_domain.system_user \
IS NOT NULL AND (LENGTH(web_domain.redirect_path)<5 OR web_domain.redirect_path IS NULL) ;"
echo $QRY | mysql -u $ispUSER -h $ispHOST -p$ispPASS | while read -r line
do # ${col[0]}=domain user / folder name / system user, ${col[1]}=clientID / system group ,
while read -a col # ${col[2]}=path to website, ${col[3]}= domain name
do
echo " "
echo " Site:" ${col[3]}
echo "-------------------------------------------------------------"
echo "Backing Up site: " ${col[2]}/ "in :" ${col[2]}/${col[3]}BU.tar.gz
cd ${col[2]}
sudo -u ${col[0]} $TAR -czf ${col[2]}/${col[3]}BU.tar.gz .
cp ${col[2]}/${col[3]}BU.tar.gz $SITES/${col[3]}.$TODAY.tar.gz
if [ `date -d '3 day ago' +%u` -ne 7 ] # if 3 days ago is not Sunday
then #remove the backup
[ -f $SITES/${col[3]}.$BACK3.tar.gz ] && rm $SITES/${col[3]}.$BACK3.tar.gz
fi
$CHOWN ${col[0]}:${col[1]} ${col[2]}/${col[3]}BU.tar.gz
$CHMOD 0660 ${col[2]}/${col[3]}BU.tar.gz
echo "-------------------------------------------------------------"
echo " "
done
done
cd $CURDIR
- 2870 megtekintés
Hozzászólások
Elég perverz tudok lenni, ha szkriptról van szó, de ilyen méretnél előbb a
set -x
kimenetét nézném át kétszer, mint magát a szkriptet egyszer.
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
set -x ahogy az előttem szóló is mondja...
parancssorból lefut?
cron-ban futtatod? ott nem megy le?
--
Debian Linux rulez... :D
- A hozzászóláshoz be kell jelentkezni
lefuttatod simán konzolon nem köhög? mit jelent a hibás zip?
- A hozzászóláshoz be kell jelentkezni
lefut konzolon és ezt adja ki:
root/scripts/mybackup.sh: line 152: sudo: command not found
cp: cannot stat `/var/www/clients/client1/web1/example.huBU.tar.gz': No such file or directory
/bin/chown: cannot access `/var/www/clients/client1/web1/example.huBU.tar.gz': No such file or directory
/bin/chmod: cannot access `/var/www/clients/client1/web1/example.huBU.tar.gz': No such file or directory
- A hozzászóláshoz be kell jelentkezni
ez eleg egyertelmu, nem? :D
- A hozzászóláshoz be kell jelentkezni
Kell az elejére egy
SUDO="$(which sudo)"
és a 152. sorban a sudo-t $SUDO-ra kell cserélni.
(hint: irónia :D )
- A hozzászóláshoz be kell jelentkezni
Mielőtt eltévedne a kedves kérdező, segítsünk is neki: olyan PATH-szal fut, ahol nem található meg a sudo (míg a többi pl. igen.) Mondjuk a sudo a /usr/local/bin -ben van, de az hiányzik a futtatókörnyezetben a PATH-ból.
- A hozzászóláshoz be kell jelentkezni
vagy nincs sudo
- A hozzászóláshoz be kell jelentkezni
csatlakozom Zahy commentjéhez: "Mielőtt eltévedne a kedves kérdező, segítsünk is neki:"
+ ne vezessük meg! biztos vagy benne, hogy mindenki veszi az adást? :D
man which:
"DESCRIPTION
which returns the pathnames of the files (or links) which would be executed in the current environment, had its arguments been given as commands in a strictly POSIX-conformant shell. It does this by searching the PATH for executable files matching the names of the arguments. It does not follow symbolic links."
a "$(which sudo)" után mi lesz a SUDO értéke, ha "...sudo: command not found" hibaüzenetet kapott?
lehet hogy Te tudod, és mások?
tehát: lehet hogy nincs a PATH-ban, lehet hogy nincs is feltelepítve, de lehet hogy "elveszett" róla az "x" permission... és lehet még sok-sok egzotikus hiba
- A hozzászóláshoz be kell jelentkezni
FOO=$(which foo )
[ -z "$FOO" -o ! -x "$FOO" ] && exit 1
Vagy például:
FOO=$( which foo || exit 1 )
[ -x "$FOO" ] || exit 1
- A hozzászóláshoz be kell jelentkezni
"a "$(which sudo)" után mi lesz a SUDO értéke, ha "...sudo: command not found" hibaüzenetet kapott?
lehet hogy Te tudod, és mások?"
Elnézést, de ez egy olyan alapszintű inteligenciateszt, hogy aki nem viszi át, az inkább ne akarjon problémát megoldani.
Ha tudunk angolul, lefordítjuk, megértjük. Ha nem, akkor a google lefordítja (speciel ezt a hibaüzenetet még megbízhatóan fordítja), és megértjük.
Tipikusan nem vagyok az, aki próbálja bevinni a bozótba a kezdőt, de könyörgöm, akár elküldhetném neki mp3-ban felolvasva a megoldást, mert ennyi erővel azt sem kéne feltételezni, hogy tud olvasni.
Én azt gondolom, hogy a kérdező miután bepostolta és elolvasta a hibaüzenetet, magától rájött a hiba okára.
- A hozzászóláshoz be kell jelentkezni
ide írom, nincs jobb 5letem:
zeller: nem adok halat
zwei: segítek megtanulni, hogyan kell halat fogni
- A hozzászóláshoz be kell jelentkezni
esetleg futtasd le így bash -x
|tee
aztán olvasd el hol akad el a script majd elemezd.
--
A legértékesebb idő a pillanat amelyben élsz.
http://phoenix-art.hanzo.hu/
https://sites.google.com/site/jupiter2005ster/
- A hozzászóláshoz be kell jelentkezni
Csak egy kis észrevétel:
scriptben egy ilyesmi elég necces:
TAR="$(which tar)"
Add meg mindenhol explicite, hogy melyiket akarod használni, ne az épp aktuális PATH-tól függjön.
Simán lehet ez is a hiba oka.
- A hozzászóláshoz be kell jelentkezni
Erre külön rá is kérdeznék.
Ennek a megoldásnak mi volna az eszmei háttere?
A which pont a PATH-ban legelöl fellelhető, adott nevű futtathatót adja vissza, ez lesz itt a TAR értéke - így a $TAR-t hívni teljes egészében megegyezik azzal, mintha ilyen körülményeskedés nélkül szerepelne a helyén, hogy tar.
Vagy valami fontosat nem látok?
- o -
A másik apróság/tanács. Mivel hajdan nekem is sokszor kellett shellből egysorosnál hosszabb SQL-t hívni, merem ajánlani a külön fájlban (lehetőleg here docokkal), jellemző néven definiált lekérdezéseket, és a fájl beszórszolását - itt is feleződne a szkript a logikát szigorúan nem érintő zagyvalék nélkül.
- A hozzászóláshoz be kell jelentkezni
Szerintem két válasz van a kérdésedre:
1. lustaság... :D majd a which megmondja, hol van az a fránya progi.
2. portolhatóság (csak hiedelem): így bárhol lefut a script, disztró függetlenül...
Persze helyből belefutunk abba, hogy adott esetben egy cron alatt futó szkript más PATH-ot kap, mint mondjuk a root, vagy egy mezei user.
És ezzel visszajutunk oda, hogy teljes útvonal nélkül megadott programnál nem biztos hogy egyáltalán vagy az a program fog-e lefutni.
Na akkor majd a which megmondja... :D vagy mégsem... -> FAIL !!!
--
Debian Linux rulez... :D
- A hozzászóláshoz be kell jelentkezni
1) lustaság nem lehetne, hisz akkor a "tar" gépelése a "TAR=$(which tar) ; $TAR" használata helyett sokkal kifizetődőbb (hisz kevesebbet kell gépelni)
2) ettől nem portolhatóbb jobban, mintha simán tar-t írnék. Ha portolható kéne legyen, akkor inkább valahogy így kéne legyen:
case `/usr/bin/uname -s` in
FreeBSD ) tar=/usr/bin/tar ;;
Linux ) tar=/bin/tar ;;
Solaris ) tar=/usr/bin/tar ;;
SunOS ) tar=/usr/ucb/bin/tar ;;
esac
És feltételezzük, hogy legalább az uname ugyanott van :-)
- A hozzászóláshoz be kell jelentkezni
Persze nem fogtad, miről beszélek...
- a user rájött, hogy a sima tar nem jó neki mert egy adott disztrón a '/bin'-ben van a tar, egy másikban meg a '/usr/bin'-ben
- viszont nem akarja minden sorba beírni, hogy '/bin/tar' mert az elgépelhető, stb... és persze nem is portolható... (lustaság)
- tehát a shell változót találta meg...
- és a which is segít neki...
- csak a path kell hogy jó legyen...
félmegoldás... de néha működik...
mondok egy érdekességet is: time parancs...
--
Debian Linux rulez... :D
- A hozzászóláshoz be kell jelentkezni
Soha nem működik, ill. soha nem működik jobban, mint kavarás nélkül a bináris közvetlen hívása, ui. a which pont azt adja vissza, és az kerül a változóba, ami egyébként is indulna.
Azaz ha a PATH korrekt, akkor azért nem kell a which; ha nem korrekt, akkor meg azért nem kell, mert az sem ad vissza semmit.
Szóval ez egy gyorsítókő.
Fickó járja a szavannát, szembejön egy másik, hatalmas húsdarabot cipel.
- Miért cipeli ezt a nagy húst ebben a tikkasztó hőségben?
- Ha jön az oroszlán, odadobom neki, és amíg jóllakik, el tudok inalni.
Fickó tovább. Aki most jön szembe, egy telefonfülke alatt nyög.
- Miért cipeli azt a fülkét?
- Ha jön az oroszlán, bebújok a fülkébe. Ha elunja, és elmegy, kijövök, és megyek tovább.
Fickó megint tovább. Most a szembejövő egy bazi követ visz.
- Mivégre ez a hatalmas kő?
- Ha jön az oroszlán, eldobom a követ, és máris gyorsabban tudok futni.
- A hozzászóláshoz be kell jelentkezni
mivel a which a PATH alapjan keres ezert nem sok teteje van ennek, boven eleg annyi h tar.
ha a tar nincs a PATH-ban, akkor azon a which sem segit.
- A hozzászóláshoz be kell jelentkezni
Mi van, ha nincs which parancs (csomag) telepítve? :P
Ha már úgyis bash és bűvészkedni akarunk, akkor legyen inkább type ;)
- A hozzászóláshoz be kell jelentkezni
De fogtam, és pont az a lényeg, hogy ettől nem lesz jobb. A "which" pontosan ugyanazt a parancsot adja vissza, mint amit a shell mindenféle hókusz-pókuszok nélkül megtalálna. Sőt rosszabb is annál, mintha csak simán beírnám a parancs nevét. Ugyanis amikor X parancsot futtatom (ahol a parancsszóban nincs pl "/"), akkor shelltől függő módon
- először megvizsgálja a shell aliasok listáját, és ha van ilyen nevű alias, akkor végrehajtódik a helyettesítés, és kezdi előlről a parancsfeldolgozást. (Nyilván olyan shellben - pl. original Bourne-shell - amiben nincs alias, ez kimarad)
- aztán a shell belső parancsok listáját
- aztán a shell-függvények listáját (nyilván ha a shellben ilyen nincs - csh, tcsh - akkor ez a lépés sem játszik)
- és csak a legvégén jön a PATH ellenőrzés.
Ha a "which" a shell beépített parancsa, akkor láthatja az első hármat, és visszaadhatja az erre vonatkozó információt (ilyen pl. a tcsh - FreeBSD-ben X éve csh néven is az érhető el), pl:
% which which
which: shell built-in command.
% which h
h: aliased to history 25
%
míg ha külső parancs, akkor az alias, belső parancs, shell-fv kategóriába tartozó dolgokat nem is látja, tehát csak a PATH-beli dolgokat találhatja meg. Viszont ha meg ezt akarja az ember elérni (azaz a PATH-beli, külső parancsot), akkor annak ennél a nyakatekert "X=$(which x)" módszernél van egyszerűbb megoldása: a parancs nevének bármelyik karakterét takard el a \ "" vagy '' kaarkterek valamelyikével, pl:
% \which which
/usr/bin/which
%
És igen, sokat lehet szívni azzal, hogy milyen "shell"ben mik a belsőleg megvalósított dolgok (kezdve a klasszikus test, [ , time , type parancsokkal), de bekavarhat pl. az, hogy Busybox a shell-ed, amibe aztán beleépítettek nem túl megszokott belső parancsokat is.
No szóval: semmi értelme nincs ennek a használati formának.
- A hozzászóláshoz be kell jelentkezni
És még mindig nem fogd, mit írok... :D
Szóval hogy egyértelműbb legyek, nem azt írom, hogy hogyan csinálnám, hanem hogy mi lehet/valószínűleg az oka, hogy így csinálja...
Én sem tenném... szerintem is hülyeség, tudatlanság... kivéve 1-2 esetet (test, time, stb..) amikor nem elég simán csak a parancsot írni..
Egyetlen értelmes módját látom, - és ezt használom is - , amire szerintem kitalálták, az az hogy le tudod ellenőrizni, hogy mit ad vissza, ergo megtalálja-e az állományt a rendszer...
setprog(){
prog=$(${which} ${1})
if [ ! -x ${prog} ]
then
echo "Missing required program: ${1}"
echo "Please install!"
exit 1
fi
declare -g ${1}=${prog}
}
setprog cat
Mondjuk ez elhal az apt-get-nél...
--
Debian Linux rulez... :D
- A hozzászóláshoz be kell jelentkezni
$ true
$ echo $?
0
$ false
$ echo $?
1
$ izemizeecet
izemizeecet: not found
$ echo $?
127
$
Ha egy szkriptben azt kell ellenőrizni, hogy van-e az adott parancs, akkor - az elvileg úgyis ellenőrizendő - státuszkód erre bőven elegendő, mint a fenti példa is mutatja. Az is igaz, hogy amióta a különböző Linux-disztró készítők kitalálták, hogy alapvetőnek tekintett eszközök opcionálisan telepíthető csomagokban vannak - aztán ennek hatására vagy van a gépen vagy nincs -, azt kell mondjam, linuxos környezetben valóban megfontolandó, hogy a programunk elején ellenőrizzük, hogy van-e tar, cp, sed, stb, és nem futás közben.
(Sikerült kihoznom, hogy szaralinux, így meggyőztél.)
- A hozzászóláshoz be kell jelentkezni
sub
- A hozzászóláshoz be kell jelentkezni
fúúú ISPConfig! :P
- A hozzászóláshoz be kell jelentkezni