PDA

View Full Version : [Thread Ufficiale] Scripting


gurutech
06-11-2009, 13:22
Lo script, un piatto finlandese...
Molti di voi avranno sentito parlare di script o scripting nell'ambito della programmazione. Ma cos'è veramente uno script?
Per script si intende un programma che viene eseguito attraverso un altro programma, chiamato interprete dello script.
Attraverso uno script vengono eseguite una serie di istruzioni e comandi che agiscono in base a dei parametri, che possono essere le condizioni del sistema in quel momento, o alcune variabili di ingresso. Uno script può anche non avere nessun parametro di ingresso, ma essere programmato per fare sempre la stessa cosa, in maniera ripetitiva, salvandoci da un bel po' di noia che si avrebbe a digitare sempre lo stesso comando.
Alcuni linguaggi di script famosi sono:

SH o shell script, interpretati da una shell *nix (la più usata in GNU/Linux è Bash)
BAT o file batch, interpretati dal CMD.EXE di Windows
Perl il cui interprete si chiama per l'appunto perl
Python il cui interprete si chiama per l'appunto python
PHP che possono essere richiamati da un server Web attraverso un modulo o da un interprete all'interno del sistema operativo
ASP che possono essere richiamati da un server Web attraverso un modulo

e molti altri non meno importanti.

...che può essere gustato in molti modi!
Tutti i sistemi operativi che io conosca hanno almeno un linguaggio di scripting a loro disposizione, più o meno potente. Come potete capire gli script ricoprono un importante ruolo nell'amministrazione del sistema, ad es. quando vogliamo automatizzare una operazione perchè venga eseguita di notte o allo stesso modo su 1000 computer. Non di meno gli script sono importanti per il World Wide Web, attraverso i quali possiamo presentare una pagina creata "al volo" per l'utente a seconda del suo comportamento.
Rimanendo a livello di sistema operativo, mentre nell'ambito Microsoft si tende ad utilizzare poco gli script, in GNU/Linux e in generale in tutti i sistemi *nix (compreso MacOSX) ricoprono una notevole importanza. Infatti l'avvio stesso del sistema operativo si svolge tramite l'esecuzione di una serie di script, e poche sono le operazioni che non si possono automatizzare con questa tecnica, dalla scrittura su CDRW al controllo della situazione metereologica.

Ingredienti di base
Ma come è fatto uno script?
Normalmente si presenta come un file di semplice testo, contenente la sequenza di comandi da eseguire. La potenza e la varietà dei comandi di cui possiamo disporre in uno script dipendono dall'interprete che intendiamo usare per lo script.
Se ad esempio uno script bash che svolge un determinato compito, può generalmente essere riscritto in perl, utilizzando un linguaggio totalmente differente. Vi sono alcune operazioni che possono essere svolte più velocemente e meglio con un linguaggio piuttosto che con un altro, ma in genere ognuno scrive utilizzando quello che conosce meglio :).

Le varie scuole di cucina
Penso di non far torto a nessuno dicendo che il linguaggio in assoluto più usato in GNU/Linux per la programmazione degli script di sistema è Bash, in stretta collaborazione con gli strumenti detti coreutils (http://www.gnu.org/software/coreutils/) e con programmi come grep, sed e awk.
Il perl la fa da padrone tutte le volte che c'è da elaborare un formato testuale in un altro formato tramite l'uso di PCRE (http://en.wikipedia.org/wiki/PCRE), o Perl Compatible regular Expression

Vediamo un esempio classico di uno script in bash

file ciao.sh

#!/bin/bash
echo "Ciao!"


questo script è composto da solo due righe, vediamo come è fatto:
la prima riga, in tutti gli script, comincia con #! seguito dal nome dell'interprete che vogliamo usare per i comandi che seguiranno
la seconda riga è un semplice comando "echo" che fa vedere a video quando scritto tra le virgolette. In bash si possono anche eseguire i costrutti classici della programmazione, come i cicli for, ad esempio con
file pingtutti.sh

#!/bin/bash
for ((n=1;n<254;n++)); do {
ping -c1 -w2 192.168.0.$n
}
done

possiamo fare un ping a tutti gli indirizzi ip da 192.168.0.1 sino a 192.168.0.254.

Tutti a tavola
Ho inaugurato questa discussione con l'intento di esplorare il misterioso mondo dello scripting, agli occhi dei profani pura magia, che è uno dei principali motivi per cui mi piace usare GNU/Linux e il free software in generale. Tramite questo topic mi piacerebbe venire a conoscenza di modi "fantasiosi" di usare strumenti come sed e awk, il perl, e quant'altro per domare il sistema e fargli fare quello che dico io, e non quello che vuole lui.
Mano a mano che posterete i vostri script li indicizzerò all'interno di questo primo post, con una breve descrizione di cosa fanno.
A, last but not least, il codice postato è libero da costrizioni, non chiedo di applicarvi la GPL (liberi di farlo se volete), ma quanto meno che ogni utente che passi di qui a leggerlo possa farvi quello che gli pare senza chiedervi il permesso, e senza che eventuali danni ricadano su di voi.

E adesso, sotto con gli script!

Indice:
sshtemp: per evitare la richiesta di autenticità di un host in connessione ssh (Bash) (http://www.hwupgrade.it/forum/showpost.php?p=29580856&postcount=2)
Reinstallare tutti i .deb che inseriscono almeno un file nella cartella data come argomento (Bash) (http://www.hwupgrade.it/forum/showpost.php?p=29588616&postcount=3)
Catturare un video da una finestra X11 (Bash + mencoder) (http://www.hwupgrade.it/forum/showpost.php?p=29593130&postcount=5)
aggiungere una progress-bar alle operazioni con i file .RAR su GNOME (PHP + Zenity) (http://www.hwupgrade.it/forum/showpost.php?p=29618441&postcount=10)

gurutech
06-11-2009, 13:33
sshtemp: per evitare la richiesta di autenticità di un host in connessione ssh

Utile per connettersi a host "temporanei" o ai quali ci si deve connettere solo una volta, e utile anche per capire come usare ssh-keyscan e ssh quando si deve scriptare richieste a interi pool di server linux.


#!/bin/bash
TARGET="$1"
echo "$1" | grep "@" 2> /dev/null &> /dev/null && TARGET=$(echo $1 | cut -d "@" -f 2)

if ( [ -z $TARGET ] ); then {
echo "Usage:"
echo " $(basename $0) [hostname]"
echo " or"
echo " $(basename $0) [username]@[hostname]"
exit 1
}
fi

REACHABLE=0
ping -c1 -w1 $TARGET 2> /dev/null &> /dev/null && REACHABLE=1

if ( [ $REACHABLE -ne 1 ] ); then {
echo "Host $TARGET is unreachable"
exit 1
}
fi

TMPFILE=$(mktemp)
ssh-keyscan -H $TARGET > $TMPFILE 2> /dev/null
ssh -o "UserKnownHostsFile $TMPFILE" $1
rm -f $TMPFILE

Gimli[2BV!2B]
06-11-2009, 22:54
Discussione interessante.
Propongo uno scriptino per distribuzioni Debian based.

Reinstallare tutti i .deb che inseriscono almeno un file nella cartella data come argomento.
Utile in caso di maldestri rm o altri disastri assortiti.
#!/bin/bash

FOLDER="$1"

if [ -z "$FOLDER" ]; then
echo "Utilizzo:"
echo -e "$(basename $0) [cartella]\n\noppure (piuttosto inutile)\n\n$(basename $0) [file]"
exit 1
fi

if [ -z "`which apt-file`" ]; then
echo -e "Installare apt-file!\n\napt-get install apt-file\napt-file update\n\n"
exit 1
fi

if [ "$(id -u)" != "0" ]; then
echo "Questo script dev'essere eseguito come root!" 1>&2
exit 1
fi

PKGS=`comm -12 <(apt-file search $FOLDER | sed 's/\([^: ]*\).*/\1/' | uniq | sort) \
<(dpkg --get-selections | grep -E \[\[:blank:\]\]install\$ | sed 's/\([^\t ]*\).*/\1/' | uniq | sort)`

apt-get install --reinstall ${PKGS}

Chiancheri
06-11-2009, 23:23
scusate, non voglio sporcare assolutamente il vostro topic, anzi, spero di parteciparvi e di contribuire attivamente. Vorrei approfittarne per chiedere 2 cose però:

1) una volta creato lo script, come si potrebbe fare per caricarlo su launchpad? so che li vanno i sorgenti dei programmi, ma che "sorgenti" ha uno script!!?? come si fa ad usare launchpad con gli script? Sono assolutamente niubbo di launchpade e vari codehosting. Mai hostato nulla finora...

2) che ne pensate di creare anche un repository comune, revisionato da tutti noi, per hostare i nostri script e renderli scaricabili e/o modificabili dagli utenti? Facciamo una piccola community magari ubuntu (debian), per script e/o programmini, tipo hwbashclan

io ad esempio sto cercando di imparare ad usare (sono alle primissime armi) le librerie grafiche (vorrei imparare le qt, per adesso ho usato solo zenity........) ed appicicarle su qualche bello script o programmino su shell che mi piace, posso provare a vestire con una gui i vostri script (anche come pacchetto a parte, scriptx-gui).

in questo momento ho creato 2 linee di script con zenity per youtube-dl, un programmino per il download di video da youtube.

gurutech
07-11-2009, 12:53
Per registrare una finestra di X11 in un filmato AVI usando:

xwd - crea uno screenshot dell'intero schermo o una singola finestra di cui si ha l'id numerico
xwininfo - fornisce informazioni sulla finestra, in particolare l'id numerico della finestra
un comanto usleep creato ad hoc che esegue una sleep per un numero specificato di microsecondi (in fondo a questo post)
all'occorenza, un paio di colpi di grep,sed,awk. insomma il copia/incolla del sistemista
ImageMagick - il coltellino svizzero per l'elaborazione seriale di immagini
Mencoder - il codificatore di filmati fornito con mplayer

ecco lo script:

#!/bin/bash
OUTDIR=$(mktemp -d)
TMPFILE=$(mktemp)
echo "Select window to be grabbed"
sleep 3
xwininfo > $TMPFILE
WINID=$(cat $TMPFILE | grep "Window id:" | awk -F "Window id: " '{print $2}' | cut -d " " -f 1)
echo "You selected $WINID"
cat $TMPFILE | grep "$WINID"
echo "Output in $OUTDIR"
echo "Press CTRL-C to stop grab"
for ((n=5;n>0;n--)); do sleep 1 && echo "Starting in $n"; done
rm -f $TMPFILE

cd $OUTDIR
i=0
while ( /bin/true ); do {
NUM=$(printf %04d $i)
i=$((i+1))
usleep 4000
xwd -id $WINID -out mov$NUM.xwd
}
done

eseguendo lo script viene chiesto di cliccare sulla finestra da registrare (il cursore diventa una "croce") e dopo 5 secondi dal click parte la registrazione. Vengono creati tutta una serie di file temporanei di tipo xwd, ciascuno dei quali contiene un frame del filmato. A questo punto possiamo convertirli in jpeg ponendoci nella directory nella quale sono stati generati e usando il seguente comando (per usare convert bisogna aver installato imagemagick)

find mov*.xwd -type f -exec basename '{}' .xwd ';' | xargs -L1 -I{} convert {}.xwd {}.jpg

(occorre un po' di tempo per la conversione, a seconda del numero di frame da convertire)
e incollare le jpg in un unico filmato utilizzando Mencoder (fornito con mplayer)

mencoder "mf://*.jpg" -mf fps=25 -o output.avi -ovc lavc -lavcopts vcodec=mpeg4

et voilà, abbiamo ottenuto il filmato desiderato.
Unica difficoltà riscontrata, ma credo sia un problema legato al programma che stavo utilizzando (DosBox), vi sono dei frame "vuoti" che vengono generati occasionalmente, e vanno eliminati prima di assemblare il filmato. Identificarli è facile, sono i file di dimensione più piccola tra quelli che abbiamo ottenuto, e hanno sempre la stessa dimensione.


usleep.c source code

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
int stime;
stime=atoi(argv[1]);
usleep(stime);
return 0;
}

gurutech
07-11-2009, 13:56
;29588616']Discussione interessante.

interessante si! sai che non conoscevo comm ?

Gimli[2BV!2B]
07-11-2009, 18:45
Riguardo a quanto proposto da Chiancheri, cavolo, vuoi fare le cose in grande... io non saprei da dove partire :fagiano:.
Intanto vediamo se si accumula un po' di materiale.

Minuscola osservazione per gurutech: perché il nanosleep compilato? sleep 0.004 non funziona bene? Oppure non è ancora disponibile in tutte le distribuzioni?

Ah, anch'io non avevo mai sentito parlare di comm prima di quest'estate :)

Chiancheri
07-11-2009, 21:13
;29597752']Riguardo a quanto proposto da Chiancheri, cavolo, vuoi fare le cose in grande... io non saprei da dove partire :fagiano:.
Intanto vediamo se si accumula un po' di materiale.

Minuscola osservazione per gurutech: perché il nanosleep compilato? sleep 0.004 non funziona bene? Oppure non è ancora disponibile in tutte le distribuzioni?

Ah, anch'io non avevo mai sentito parlare di comm prima di quest'estate :)

per prima cosa ho aperto intanto il mio repo. Ora voglio creare come primo programma una specie di SDK per caricare in 4 e 4 = 8 ogni script su launchpad, in pochissimi clic, automatizzando le operazioni di make e dput

gurutech
08-11-2009, 18:08
;29597752'] Minuscola osservazione per gurutech: perché il nanosleep compilato? sleep 0.004 non funziona bene? Oppure non è ancora disponibile in tutte le distribuzioni?


perchè se avessi letto la pagina di manuale (come ho fatto ora) avrei scoperto che accetta anche i floating point e non solo gli interi! :)

flx2000
09-11-2009, 14:39
Un paio di anni fa ho creato una coppia di script PHP che usano l'applicazione zenity per aggiungere una progress-bar alle operazioni con i file .RAR su GNOME (ad esempio Ubuntu).

Per utilizzare gli script basta aggiungere il primo alle azioni di Nautilus in "Sistema->Preferenze->Configurazione azioni di Nautilus" in modo che lo script sia richiamabile cliccando col tasto destro del mouse su un file o su una directory, e mettere il secondo in una qualsiasi directory nel PATH.

rarmax-action.php :

#!/usr/local/bin/php
<?PHP

/**
* rarmax-action v1.0
* by Fabio "FLX" Addari
*
* Script che dà un apporto grafico alla compressione dei file rar
*
**/

if ( count($argv) < 4 )
{
$x=`zenity --warning --text="Nessun file selezionato" --title="rarmax: avviso"`;
exit;
}

$elems = array();

reset($argv);
list(,) = each($argv); // salta il nome dello script
list(,$dir) = each($argv);
list(,) = each($argv); // salta il primo file perché viene ripetuto
while ( list(,$elem) = each($argv) )
{
$elems[] = $elem;
}

$workdirfile = ( count($elems) == 1 ) ? $elems[0] : basename($dir);
$workdirfile .= ".rar";

while ( true )
{
$archivio = `zenity --entry --entry-text="{$workdirfile}" --text="Nome dell'archivio" --title="rarmax: archiv
io"`;
$archivio = trim($archivio);

if ( empty($archivio) )
{
exit;
}
elseif ( substr($archivio,0,1) != "." )
{
break;
}

$x = `zenity --warning --text="Nome del file non valido" --title="rarmax: avviso"`;
}

if ( strripos($archivio,".rar") !== (strlen($archivio) - 4) )
{
$archivio .= ".rar";
}

if ( file_exists("{$dir}/{$archivio}") )
{
$x = `zenity --question --title="rarmax: avviso" --text="Sovrascrivere {$archivio}?" && echo s`;
if ( strpos($x,"s") === false )
{
$x = `zenity --info --text="Operazione annullata" --title="rarmax: avviso"`;
exit;
}
}

$tmpfile = tempnam("/tmp","~rarmax-");

$tmp = fopen($tmpfile,"w");
foreach ( $elems as $elem )
{
fputs($tmp,"\"{$elem}\"\n");
}
fclose($tmp);

$x = `cd "$dir";rar a -m5 -md4096 -r -s "{$archivio}" @{$tmpfile} | rarmax-parse.php | zenity --progress --percentage
=0 --text="Compressione di {$archivio} in corso..." --title="rarmax: compressione" --auto-close`;

unlink($tmpfile);

?>


rarmax-parse.php :

#!/usr/local/bin/php
<?PHP

/**
* rarmax-parse.php
*
* Versione 1.0 by Fabio "FLX" Addari
*
* Questo script riceve in ingresso l'output del comando rar e pone in
* uscita la percentuale di completamento, da 0 a 100.
**/

$input = fopen("php://stdin","r");
$output = fopen("php://stdout","w");

$x = "";
$waiting = false;
$prec = 0;
while ( !feof($input) )
{
$c = fgets($input,8);
$x .= $c;

if ( strpos($c,chr(8)) !== false )
{
//fputs($output,"Letto: '{$x}'\n");

$put = preg_replace("/[^0-9]/","",$x);

if ( $put > 100 )
{
$put = 0;
}

if ( $waiting )
{
if ( $prec > 0 )
{
$put = $prec.$put;
}
$waiting = false;
}
elseif ( $put > 0 && $put < $prec )
{
$waiting = true;
$prec = $put;
$x = "";
continue;
}

if ( !empty($put) )
{
fputs($output,"{$put}\n");
}

$x = "";
$prec = $put;
}
}

fclose($output);
fclose($input);

?>

masand
11-11-2009, 09:42
Ottimo Topic.

Ma per farlo diventare ufficiale manca qualche informazione:

Cosa è lo scripting?
Cosa posso farci con lo scripting?
Introduzione allo scripting su e/o sistemi alternativi
Linguaggi subito disponibili sulle distribuzioni


Dopodiché sarebbe ottimo, anche se chi posta i propri script possa anche spiegare (o riga per riga o in generale) il funzionamento e come usarlo.

Un saluto a tutti...
masand

gurutech
11-11-2009, 09:49
Ottimo Topic.

Ma per farlo diventare ufficiale manca qualche informazione:

Cosa è lo scripting?
Cosa posso farci con lo scripting?
Introduzione allo scripting su e/o sistemi alternativi
Linguaggi subito disponibili sulle distribuzioni


Dopodiché sarebbe ottimo, anche se chi posta i propri script possa anche spiegare (o riga per riga o in generale) il funzionamento e come usarlo.

Un saluto a tutti...
masand

ok scrivo io una intro

Chiancheri
12-11-2009, 02:48
SALVEEEEE!!!


ho creato uno script (e l'ho pacchettizzato e hostato su launchpad DA SE), il quale ti fa le seguenti domande:

1) nome del programma

2) descrizione

3) nome del tuo repository

4) seleziona cartella di lavoro

5) seleziona script (coi permessi già dati)

6) seleziona icona .png

7) immetti la versione del programma a cui sei giunto

8) immetti le dipendenze

9) immetti la categoria




E VOILA'


carica tutto sul repository di launchpad e lo rende disponibile a tutti!!!!!!


con tanto di icona e di programma visibile nel menu di gnome!!


ottimo per programmi che abbiano un minimo di gui!



al momento ho creato la versione BASE poi voglio migliorarla un pò (se mi aiutate è meglio)

per aggiungere il mio repository (su karmic)

sudo apt-add-repository ppa:ing.gonzo

(https://launchpad.net/~ing.gonzo/+archive/ppa)

il programma si chiama ugbu

N.B.

sempre se uno ha già un account attivo e configurato su launchpad, con tanto di chiave registrata e tutto.

Chiancheri
12-11-2009, 13:05
adesso che abbiamo un programmino che pacchettizza e condivide su launchpad gli script, perchè (alcuni) non li carichiamo su launchpad? mettetegli zenity per inserire i dati (fa schifo ma è già una gui di dialog) e ci facciamo un repository comene,

CHE NE DITE???

masand
24-11-2009, 10:32
Spostato nelle Discussioni Ufficiali.

Mi scuso per il ritardo :stordita:

FagioloOne
17-04-2010, 18:30
Ho una domanda a proposito delle variabili nella shell, se qualcuno potrebbe aiutarmi gli sarei immensamente grato.

Il problema e' il seguente:

Ho due stringhe str1 e str2

Vorrei che la stringa str1str2 fosse vista come una variabile dal shell, grazie.

Esempio variabile CASAMIA

str1 = CASA
str2 = MIA

str1str2 eviquivalere alla variabile CASAMIA.

grazie di tutte le risposte.

Gimli[2BV!2B]
17-04-2010, 18:53
Non sono certo di aver capito al 100%, soprattutto per l'assenza di un frammento di codice esplicativo.

Un'idea comunque me la sono fatta, vuoi richiamare una variabile il cui nome è contenuto in un'altra (o più) variabili? (http://www.linuxquestions.org/questions/linux-newbie-8/problem-with-bash-script-variable-name-within-variable-name-710320/)

FagioloOne
18-04-2010, 07:57
Grazie dell'aiuto era esattamente quello che stavo cercando ma il problema e' il mio script non puo' essere scritto in bash e quindi la soluzione trovata non posso utilizzarla.
Ho usato percorso altre vie.

Grazie dell'aiuto.

Gimli[2BV!2B]
16-06-2010, 23:40
Riporto un paio di link a discussioni recenti sull'argomento script.

Eliminare file con la stessa estensione (http://www.hwupgrade.it/forum/showthread.php?t=2187644)
Rinominare files in base alla data di creazione (http://www.hwupgrade.it/forum/showthread.php?t=2183154)


Qualche giorno fa ho anche aggiornato il downloader "Alle otto della sera" (http://www.hwupgrade.it/forum/showthread.php?t=2067189), progettino che mi ha dato molti spunti per sperimentare con espressioni regolari, ridirezioni stream e qualche tentativo di gestione degli errori un po' "avanzato".

Gimli[2BV!2B]
27-09-2011, 19:43
Backup di database MySQL
Parametri da linea di comando:

all -> esegue il backup dei database elencati da "SHOW DATABASES"
"nome_db1 nome_db2 nome_dbN" -> esegue il backup dei soli database specificati

Variabili personalizzabili:

/etc/FILE_ACCESSO -> file contenente i dati di accesso al/ai datanase da salvare: USR e PWD
MAX_BACKUPS -> Numero di backup da mantenere
SKIP -> Database da NON salvare
DEST -> Cartella di destinazione backup: al suo interno verrà creata una cartella apposita
MBD -> Cartella da creare all'interno della cartella di destinazione
RIGHTS_DIR -> Diritti ottali da assegnare a directory di backup
RIGHTS_TAR -> Diritti ottali da assegnare ad ogni file gz creato
#!/bin/bash
# Backup MySql databases
# --------------------------------------------------------------------
# This is a free shell script under GNU GPL version 2.0 or above
# Copyright (C) 2004, 2005 nixCraft project
# Feedback/comment/suggestions : http://cyberciti.biz/fb/
# -------------------------------------------------------------------------
# Copyleft (C) 2011-2012 Gimli
# -------------------------------------------------------------------------
# 20110922 - v1.0
# 20110923 - v2.0
# 20120716 - v3.0
# 20120717 - v3.1
# 20120718 - v3.2
# -------------------------------------------------------------------------

# Inclusione per prima: precedenza a parametri impostati in questo script
. /etc/FILE_ACCESSO

###########################################################################
# ------------------------------------------------------------------------#
# Impostazioni personalizzabili - inizio
#
# Numero di backup da mantenere
MAX_BACKUPS=30

# Nome host server MySQL (opzione -h mysqldump)
MyHOST="localhost"

# Database da NON BACKUPPARE
SKIP=""

# Cartella di destinazione backup: al suo interno verrà creata una cartella
# apposita
DEST="/home/gimli/backup"

# Cartella da creare all'interno della cartella di destinazione
# (poò anche essere uguale DEST: i diritti non saranno modificati)
MBD="$DEST/mysql"

# Diritti ottali da assegnare a directory di backup
RIGHTS_DIR="0700"
# Diritti ottali da assegnare ad ogni file gz creato
RIGHTS_TAR="0600"
#
# Impostazioni personalizzabili - fine
# ------------------------------------------------------------------------#
###########################################################################

###########################################################################
# ------------------------------------------------------------------------#
# Percorsi assoluti binari utilizzati (importanti per crontab)
#
# mysql usato per 'SHOW DATABASES'
MYSQL="$(which mysql)"
MYSQLDUMP="$(which mysqldump)"
CHOWN="$(which chown)"
CHMOD="$(which chmod)"
#COMPRESSOR="$(which gzip)"; EXTENSION="gz"
COMPRESSOR="$(which bzip2)"; EXTENSION="bz2"
#COMPRESSOR="$(which xz)"; EXTENSION="xz"
SED="$(which sed)"
HOSTNAME="$(which hostname)"
#
# Percorsi assoluti binari utilizzati - fine
# ------------------------------------------------------------------------#
###########################################################################

usage()
{
cat << EOF
utilizzo: $0 opzioni

Questo script esegue backup di database mysql.
Specificare una delle seguenti azioni:
all : backup dei database elencati da "SHOW DATABASES"
like '%condizione%' : backup dei database che soddisfano la condizione.
test '%condizione%' : mostra i database che soddisfano la condizione.
"nome_db1 nome_db2 nome_dbN" : backup dei soli database specificati.

EOF
}

# Lista di database
TEST=0
if [ "$1" == "test" ]; then
TEST=1
fi
DBS=$(if [ -z "$1" ]; then
:
elif [ "$1" == "all" ]; then
echo 'show databases' | $MYSQL -u $USR -h $MyHOST --password="$PWD" -Bs
elif [ "$1" == "like" ]; then
echo "SHOW DATABASES LIKE '$2'" | $MYSQL -u $USR -h $MyHOST --password="$PWD" -Bs
elif [ "$1" == "test" ]; then
echo "SHOW DATABASES LIKE '$2'" | $MYSQL -u $USR -h $MyHOST --password="$PWD" -Bs
else
echo "$1"
fi)

if [ -z "$DBS" ]; then
echo "Nessun database selezionato!"
usage
exit 1
fi

if [[ TEST -eq 1 ]]; then
for db in $DBS ; do
skipdb=0
if [ "$SKIP" != "" ] ; then
for i in $SKIP ; do
[ "$db" == "$i" ] && skipdb=1 || :
done
fi

if [[ $skipdb -eq 0 ]] ; then
echo $db
fi
done
exit 0
fi

# Creazione cartella destinazione e impostazione diritti
[ ! -d $MBD ] && mkdir -p $MBD || :
if [ "$MBD" != "$DEST" ]; then
# owner root
$CHOWN 0.0 -R $MBD
# Applica diritti
$CHMOD $RIGHTS_DIR $MBD
fi

# hostname: utilizzato in nome file
HOST="$($HOSTNAME)"
# data: utilizzata in nome file
NOW="$(date +"%Y-%m-%d_%H.%M")"

for db in $DBS ; do
skipdb=0
if [ "$SKIP" != "" ] ; then
for i in $SKIP ; do
[ "$db" == "$i" ] && skipdb=1 || :
done
fi

if [[ $skipdb -eq 0 ]] ; then
# Inizio nome file per conta (paranoia spazi)
FILE_PREFIX="$(echo "$MBD/$db.$HOST" | tr -d [:blank:])"
# Nome nuovo backup (paranoia spazi)
FILE="$(echo "$FILE_PREFIX.$NOW.sql.$EXTENSION" | tr -d [:blank:])"
# Elenco backup precedenti (paranoia rimozione spazi, poi testo esistenza file)
FILE_PREV=( $(ls "$FILE_PREFIX"*.sql.* 2>/dev/null | tr -d [:blank:]) )
# Mantengo solo gli ultimi $MAX_BACKUPS - 1 (a cui si sommerà il nuovo)
if (( ${#FILE_PREV[@]} > (($MAX_BACKUPS - 1)) )) ; then
let "NUM_DEL=${#FILE_PREV[@]} - $MAX_BACKUPS + 1"
for (( ; NUM_DEL > 0; NUM_DEL-- )) ; do
if [ -f "${FILE_PREV[$NUM_DEL]}" ] ; then
rm "${FILE_PREV[$NUM_DEL]}"
fi
done
fi

ERROR_MESSAGE=$( {
$MYSQLDUMP --add-drop-database --quick -c -e -F -l -u $USR -h $MyHOST --password="$PWD" --databases $db | \
$SED -e 's|/\*\!40000 DROP DATABASE IF EXISTS \(`.*`\)\*/;|DROP DATABASE IF EXISTS \1;|' | \
$COMPRESSOR > "$FILE" ;
if [[ ${PIPESTATUS[0]} -ne 0 ]] ; then
exit 1
elif [[ ${PIPESTATUS[1]} -ne 0 ]] ; then
exit 2
elif [[ ${PIPESTATUS[2]} -ne 0 ]] ; then
exit 3
fi
exit 0
} 2>&1 )
RETURN=$?

if [[ $RETURN -ne 0 ]] ; then
if [ -f "$FILE" ] ; then
rm "$FILE"
fi
# mysqldump o gzip fallito!
FILE="$MBD/_FAILED.$db.$HOST.$NOW.FAILED_.txt"
touch "$FILE"
echo "$ERROR_MESSAGE" > "$FILE"
fi
# Applica diritti al file
$CHMOD $RIGHTS_TAR "$FILE"
fi
done
Avete suggerimenti per semplificare i vari salti mortali che ho utilizzato per intercettare valore di ritorno e messaggi di errore di mysqldump e gzip?

luipez
12-01-2017, 10:34
Sono un utente WIN che tramite l'uso del Raspberry si sta approcciando a Linux.

Vorrei fare un file (tipo BAT o CMD in Win) che mi mandi in esecuzione i seguenti comandi:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade -y
sudo apt-get autoclean
sudo apt-get clean
sudo apt-get autoremove -y

Il file lo vorrei tenere sul desktop di Jessy/Pixel per poterlo lanciare all'occorrenza.

E' possibile?

Mi aiutate?

luipez
19-01-2017, 15:28
Comunico che ho risolto tramite quest'altro thread:

https://blog.robseder.com/2015/09/29/scripts-to-update-the-raspberry-pi-and-debian-based-linux-distros/

Spero possa essere di aiuto a qualcun altro.

luipez
19-01-2017, 15:37
Dimenticavo,

l'ho tradotto anche in italiano.

vinny74
26-02-2017, 07:41
Ciao scusate visto che qui si parla di scripting sto cercando di farne uno che tramite grep e sed o awk elimini delle righe specifiche all'interno di un file.

Dato il file di esempio file.user.
Il file è così composto:


[account]
user = ciao
password = 3

[account]
user = prova
password = hey
log = /home/prova/prova.log

[account]
user = pernoi


Come si vede l'unica vera costante nel file è la stringa [account] e tramite varie guide e un po di prove ho scritto questa riga che mi consente di creare un array con le righe dove è presente [account]

RIGHE=($(grep -n "\[account\]" file.user | sed 's/:.*//'))

Adesso dovrei scrivere qualcosa che dato l'array controlli se nell'intervallo tra il primo indice e il secondo è presente l'user prova, se non lo trova esegue il controllo tra il secondo indice ed il terzo e così via.
Se lo trova cancella tutte le righe comprese nell'intervallo tranne l'ultima, ovvero nel file di esempio deve cancellare tutte le righe dalla 5 alla 9.
Avevo pensato a sed ma non riesco a capire come dirgli di controllare se esiste una determinata stringa in un intervallo di righe.

Spero di essermi spiegato bene.
Grazie

Gimli[2BV!2B]
05-10-2018, 22:09
Versione di sviluppo di uno script per restore parallelo di una serie di database MySQL compressi in bz2.
Potrebbero esserci imprecisioni, l'ho poi affinato sul sistema di destinazione dove è entrato in produzione.
#!/bin/bash

# Restore MySql database backups
# --------------------------------------------------------------------
# This is a free shell script under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# Copyleft (C) 2011-2018 Gimli
# -------------------------------------------------------------------------
# 20171109 - v1.0.0
# 20180131 - v1.0.1
# 20180405 - v1.0.2 test again if database mysql is being processed and ask
# 20180911 - v1.0.3 DECOMPRESSOR variable, and MySQL SESSION variables
# 20181001 - v2.0.0 parallel
# -------------------------------------------------------------------------

usage()
{
cat << EOF
utilizzo: $0 "pattern"

Questo script esegue il restore di database mysql sul server locale.
Consuma file compressi con bz2 (teoricamente creati con backup.sh)
Specificare un solo parametro:
"\backup\mysql\*.2017-11-09_04.00.sql.bz2" pattern match dei file da ripristinare

EOF
}

# this function is called when Ctrl-C is sent
function trap_ctrlc ()
{
# perform cleanup here
printf "\n\nCtrl-C caught... "
stty echo
echo "exit."

# exit shell script with error code 3
exit 3
}

# initialise trap to call trap_ctrlc function
# when signal 2 (SIGINT) is received
trap "trap_ctrlc" INT

if [ -z "$1" ]; then
echo "Nessun file specificato!"
usage
exit 1
fi

FILES="$1"

echo "Decompressor: "
DECOMPRESSOR="$(which lbunzip2 2>/dev/null)";
if [ -z "$DECOMPRESSOR" ]; then
DECOMPRESSOR="$(which pbunzip2 2>/dev/null)";
fi
if [ -z "$DECOMPRESSOR" ]; then
DECOMPRESSOR="$(which bunzip2)";
fi
printf " $DECOMPRESSOR\n\n"

echo "Parallel: "
ENV_PARALLEL="$(which env_parallel.bash 2>/dev/null)"
if [ -z "$ENV_PARALLEL" ]; then
printf " NOT available\n\n"
else
printf " $ENV_PARALLEL\n\n"
. $ENV_PARALLEL
fi

echo "Restoring files matching: "
printf " $FILES\n\n"
list=($FILES)
echo "Matched ${#list[@]} files:"
for file in "${list[@]}"; do
if [ -f "$file" ]; then
echo " $file";
else
echo " NO VALID MATCHES: check the argument passed to the script"
exit 2
fi
if [[ $file == */mysql\.* ]] || [[ $file == ^mysql\.* ]]; then
echo "################################################################################"
echo "WARNING! Is this the mysql database? This will overwrite users, grants, etc..."
echo -e "################################################################################\n"
fi
done
printf "\n\n"
echo "INFO: press CTRL C to abort, at any time (be aware that this will *kill* the restore at the point reached)"

stty -echo
printf "MySQL root password: "
read PASSWORD
stty echo
printf "\n"

printf "Start: "
date
SECONDS=0

FILES_TOT=0
FILES_CONFIRMED=()
for file in $FILES ; do
if [[ $file == */mysql\.* ]] || [[ $file == ^mysql\.* ]]; then
echo "################################################################################"
echo "WARNING! Is this the mysql database? This will overwrite users, grants, etc..."
echo -e "################################################################################\n"
printf "Press [Y]es to continue, [N]o or Ctrl C to skip\n"
while true; do
read -p "" yn
case $yn in
[Yy]* ) FILES_CONFIRMED+=("$file"); break;;
[Nn]* ) printf "\nSkipped file:\n$file\n"; break;;
* ) echo "Please answer Yes or No";;
esac
done

printf "\n"
else
FILES_CONFIRMED+=("$file")
((FILES_TOT++))
fi
done

filter_sql()
{
sed -e '1s|^|SET SESSION myisam_sort_buffer_size = 5*1024*1024*1024;|' \
-e '1s|^|SET SESSION read_buffer_size = 256*1024*1024;|' \
-e 's|/\*\!40000 ALTER TABLE \(`.*`\) DISABLE KEYS \*/;|ALTER TABLE \1 DISABLE KEYS;|' \
-e 's|/\*\!40000 ALTER TABLE \(`.*`\) ENABLE KEYS \*/;|ALTER TABLE \1 ENABLE KEYS;|'
}

restore()
{
CMD_TIME="$(which time)"
if [ -z "$ENV_PARALLEL" ]; then
printf "\nFile [%2s/$FILES_TOT] -> $1\n" "$2"
CMD_PV="pv -fperb"
pv "$1" | $DECOMPRESSOR | filter_sql | MYSQL_PWD="$PASSWORD" mysql -uroot
else
printf '\n\n%*s' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
printf "\nFile terminato [%2s/$FILES_TOT] -> %-55s " "$2" "$1"
CMD_PV="pv -fa"
( pv -fa "$1" | $DECOMPRESSOR | filter_sql | MYSQL_PWD="$PASSWORD" TIME="Time %E" $CMD_TIME mysql -uroot 2>&1 ) 2>&1
fi
}

if [ -z "$ENV_PARALLEL" ]; then
count=1
for file in $FILES ; do
restore $file $count
((count++))
done
else
env_parallel -j-1 --bar --env PASSWORD --env DECOMPRESSOR --env FILES_TOT --env ENV_PARALLEL --env filter_sql --env restore restore {} {#} ::: "${FILES_CONFIRMED[@]}"
fi

printf "Exit: "
date
echo "Elapsed seconds: $SECONDS"

Esempio di utilizzo:
sertan ~/restore # ls -la sql/
totale 5020
drwxr-xr-x 1 root root 212 29 set 01.27 .
drwxr-xr-x 1 root root 102 5 ott 22.55 ..
-rw-r--r-- 1 root root 5073345 29 set 00.38 amarokdb_20180929.sql.bz2
-rw-r--r-- 1 root root 3659 29 set 00.39 elips_20180929.sql.bz2
-rw-r--r-- 1 root root 53964 29 set 01.27 tc_20180929.sql.bz2
-rw-r--r-- 1 root root 2138 29 set 00.39 ww_20180929.sql.bz2
sertan ~/restore # restore.sh "sql/*"
Decompressor:
/usr/bin/lbunzip2

Parallel:
/usr/bin/env_parallel.bash

Restoring files matching:
sql/*

Matched 4 files:
sql/amarokdb_20180929.sql.bz2
sql/elips_20180929.sql.bz2
sql/tc_20180929.sql.bz2
sql/ww_20180929.sql.bz2


INFO: press CTRL C to abort, at any time (be aware that this will *kill* the restore at the point reached)
MySQL root password:
Start: ven 5 ott 2018, 22.57.30, CEST
[...]
Exit: ven 5 ott 2018, 22.57.36, CEST
Elapsed seconds: 6