Opzioni da linea di comando con getopts

Nei miei script di studio, per il passaggio di dati agli script, fino ad ora, ho utilizzato i parametri posizionali ($1, $2,…${N}); è ora di imparare ad usare degli indici letterali come negli script “seri” del tipo:

nomescript -a parametro -b altro Parametro.

Per fare quello che voglio, ho trovato due possibili comandi: “getopts” e “getopt”; il primo, a differenza del secondo, non ammette l’uso di “stringhe opzione lunghe” (–opzione) ma solo ad un carattere (-a), ma ha il vantaggio di essere un “builtin” quindi presente di default in Bash; per questo motivo parlerò di “getopts”.

Ho fatto un piccolo script per le prove (più in basso) e mi segnerò su questa pagina qualche annotazione utile sull’uso del comando.

USO di base

Per prima cosa vanno decise le lettere da usare come opzioni letterali nel mio caso ‘a, b, c, d, e, h’ nell’utilizzo sulla linea di comando devono essere precedute dal “-” (meno) ed inserite singolarmente (non: ‘script -abc’ ma ‘script -a -b -c’ ).

Per l’utilizzo pratico conviene inserirle in un ciclo while con case, vedere lo script ed i commenti:

#!/bin/bash
clear script=$(basename $0)
help=”Questo script, ‘$script’, serve solo per vedere l’uso di getopts quindi affinché venga eseguito correttamente occorre passare almeno un’opzione. Le opzioni accettate sono: ‘-a’, ‘-b’, ‘-c’, ‘-d’, ‘-e’ e ‘-h’
Le opzioni ‘a,b,c,d,e’ mostrano solo l’opzione passata ed il proprio eventuale argomento. L’opzione ‘-h’ mostra l’help Solo ‘-c’ accetta un argomento, da passare da linea di comando, dopo l’opzione. Il ‘-‘ (meno) identifica, nella lettera che segue, un’opzione.\n Es.:./opzioni_prova.sh -a -b -c prova -d -e -h
# Controllo che sia stato passato almeno un argomento
if [ $# -eq 0 ] # se lo script è eseguito senza argomenti…
then
echo -e “$help” # … stampo l’help…
exit 1 # … ed esco.
fi
while getopts “:abc:deh” opzione # Dichiaro le opzioni accettate e il tipo
# i ‘:’ (due punti) iniziali sopprimono i messaggi di errore
# i ‘:’ (due punti) dopo un’opzione significano che ci si aspetta un argomento.
# Occhio! Qualsiasi cosa dopo ‘-c’ viene preso come argomento di ‘-c’
do
case $opzione in
# $OPTIND è il puntatore (numerico) all’opzione successiva
# $OPTARG è l’argomento passato, se esiste
a ) echo -e “\nhai inserito l’opzione -a con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
b ) echo -e “\nhai inserito l’opzione -b con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
c ) echo -e “\nhai inserito l’opzione -c con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
d ) echo -e “\nhai inserito l’opzione -d con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
e ) echo -e “\nhai inserito l’opzione -e con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
h ) echo -e “\n$help”;; * ) echo -e “\nÈ stata inserita un’opzione non valida.\n\n $help”;;
esac
done shift $(($OPTIND – 1)) # resetto (come $OPTIND=1)
# Sposta il puntatore all’opzione che segue per esempio il parametro posizionale $1.
exit 0

Nella riga while getopts “:abc:deh” Opzione i primi : (due punti) servono per utilizzare il comando in modalità silenziosa, sopprimendo gli eventuali messaggi di errore.

I : (due punti) posti dopo la lettera c servono ad indicare che l’opzione -c accetta un parametro obbligatorio, se il parametro non viene inserito verrà preso come parametro qualsiasi stringa seguente -c quindi attenzione!

Nella stessa riga, la stringa “opzione” è la variabile impostata dal ciclo while che verrà utilizzata nel costrutto case.
Le righe in case sono quasi tutte del tipo:

a ) echo -e “\nhai inserito l’opzione -a con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
servono solo per mostrare i valori dell’opzione passata, il valore di $OPTIND (che è l’indice numerico dell’opzione successiva) e dell’eventuale valore del parametro passato, contenuto in $OPTARG.
La riga:
h ) echo -e “\n$help”;;
a differenza delle precedenti stampa a video solo quanto scritto nella variabile $help.
La riga:
* ) echo -e “\nÈ stata inserita un’opzione non valida.\n\n $help”;;
intercetta tutto quanto è diverso dalle opzioni indicate precedentemente, quindi le opzioni non valide, informa del fatto e mostra l’help.
La riga:
shift $(($OPTIND – 1))
serve a “resettare” $OPTIND equivale a $OPTIND=1. Dopo aver resettato si potrebbero usare gli eventuali parametri posizionali o anche ripetere il ciclo precedente

Le prove

Conviene scaricare lo script opzioni_prova.sh renderlo eseguibile e provarlo; inizialmente in modo corretto con: ./opzioni_prova.sh -a -b -c prova -d -e -h in seguito conviene provare a passare dati incompleti, con parametro e senza, sbagliati etc. si comprenderà facilmente la forza ed i limiti del comando.

Ricercare i pdf e nei pdf

Un amico mi chiese una applicazione per poter cercare nei pdf….. 2 soluzioni

a) recoll http://www.lesbonscomptes.com/recoll/download.html#general

b) pdfgrep https://gitlab.com/pdfgrep/pdfgrep

presenti sia sotto linux che sotto windows.

Lo script per estrarre pagine pdf da un file pdf piu’ grande il file si chiama pdfselect.sh

#!/bin/bash
# extract pages from a big pdf file using gs
# Usage:
#           pdfselect.sh pdffile startPageNumber endPageNumber

function getPDFPages()
{
if [ -e $1 ]; then
pdfinfo $1 | grep Pages | awk {print $2}
else
echo 0;
fi
}

if [ $# -lt 2 ]; then
sed -n 3,4p `which pdfselect.sh`
exit
fi

oriPdf=$1
[ ! -e ${oriPdf} ] && echo ${oriPdf} does not exist! && exit

numPage=`getPDFPages ${oriPdf}`
[ ${numPage} -eq 0 ] && ZERO page is found in ${oriPdf} && exit

sPage=$2
[ ${sPage} -gt ${numPage} ] && ${sPage}=${numPage}
i

———————- SCRIPT FILE ESTRATTORE DI PAGINE DA FILE PDF IN BASE ALLA RICERCA ——

# ./extract_pdf_results.sh Lagrange ./test.pdf
# ./extract_pdf_results.sh “Text” $file

STRING=”$1″
FILE=”$2″
FILENAME=”${FILE##*/})”
BASENAME=”${FILENAME%.*}”
DIRNAME=”${FILE%/*}”

echo “Processing $FILE…”

## find pages that contain string, remove duplicates, convert newlines to spaces

echo “Looking for $STRING…”

PAGES=”$(pdfgrep -n “$STRING” “$FILE” | cut -f1 -d “:” | uniq | tr ‘\n’ ‘ ‘)”

echo “Matching pages:
$PAGES”

## extract pages to new file in original directory

echo “Extracting result pages…”

pdftk “$FILE” cat $PAGES output “${DIRNAME}/${BASENAME}_pages_with_${STRING}.pdf”

echo “Done.”

—— SCRIPT CHE COPIA FILE PDF CHE CONTENGONO STRINGA IN UNA OPPORTUNA DIR —

#!/bin/bash
# Ricerca Testo e copia file presso la directory di destinazione
# bash pdfgrepandmv.sh “Text” “./target/*” “./destination/”

while read line; do
file=$(echo $line|awk -F: ‘{print $1}’)
printf “$file: ”
echo “$line”|grep -q :0$ && echo STRINGA NON TROVATA! && continue
echo STRINGA TROVATA
cp -i “$file” $3
done < <(find $2 -type f -iname ‘*.pdf’ -exec pdfgrep -Hc “$1” {} \;)

Installare i pacchetti su linux Ubuntu

Debian e Ubuntu

Comandi per gestire i pacchetti  in Ubuntu, Debian e distribuzioni derivate: installare applicazioni eliminare,  cercare.

Comando dpkg

Installare un file .deb

sudo dpkg -i package_file.deb

Qualora ci siano problemi di dipendenze nell’installazione del pacchetto lanciare  di seguito

sudo apt-get -f install 

ed eventualmente nuovamente il comando  sudo dpkg -i package_file.deb

Rimuovere .deb file

sudo dpkg -r package_name

Per rimuovere pacchetti che danno problemi di rimozione con apt-get remove si può provare

sudo dpkg -P package_name

Cercare un pacchetto installato con dpkg

dpkg -l libgtk[0-9]* | grep ^i 

Visualizzare  tutto i pacchetti il software installato con dpkg

dpkg -get-selections 

Provare a riparare i pacchetti danneggiati

sudo dpkg --configure -a

Per elencare i pacchetti disponibili si può usare

sudo dpkg -l php*

Per elencare i pacchetti installati si può usare

sudo dpkg -l | grep php

Comando apt-get

apt-get ( advanced packagind tool è il gestore dei pacchetti standard della distribuzione Debian e anche della derivata Ubuntu

installare il pacchetto “package” con

sudo apt-get install package

cercare un pacchetto nella cache di apt-get

sudo apt-cache search mysql 

Per ottenere dettagli su un pacchetto utilizzare il comando

apt-cache policy mysql-server

Rimuovere il pacchetto “package” con

sudo apt-get remove package

Rimuovere il pacchetto package con tutti i files di configurazione

sudo apt-get --purge remove package

Rimuovere il pacchetto package con tutte le dipendenze inutilizzate

sudo apt-get autoremove package

Riparare le dipendenze dei pacchetti non soddisfatte

sudo apt-get -f install 

Convertire i pacchetti  .rpm

Convertire i pacchetti .rpm. in pacchetti .deb

sudo alien -k file.rpm

Repository importare chiave di autenticazione

Per importare la chiave di autenticazione di un repository utilizzare un comando del tipo che segue sostituendo con il numero della chiave le X :

gpg --keyserver keyserver.ubuntu.com --recv XXXXXXXX && gpg --export -a XXXXXXXX | sudo apt-key add -

Ubuntu – Debian

Controllare e risolvere eventuali errori o dipendenze rotte con:

sudo apt-get check 
sudo apt-get -f install

Provare a riparare pacchetti danneggiati

sudo dpkg --configure -a

Reinstallazione  ubuntu debian

Reinstallare da zero un sistema ubuntu o debian linux con tutti i pacchetti di una altra installazione.

Salvare la lista dei pacchetti in un file

sudo dpkg -get-selections > package_installed.txt

Utilizzare la lista dei pacchetti salvata per installare lo stesso software anche nel nuovo sistema

sudo dpkg -set-selections < package_installed.txt && apt-get dselect -upgrade

Ubuntu aggiornamenti ( update )

Per aggiornare la lista dei pacchetti disponibili

sudo apt-get update 

Scaricare e installare gli aggiornamenti per tutti i pacchetti installati

sudo apt-get upgrade 

Ubuntu upgrade di versione

Per aggiornare l’intero sistema ad una nuova versione

sudo do-release-upgrade

o

sudo apt-get dist-upgrade 

oppure è possibile digitare la combinazione Alt+F2 e scrivere

update-manager -d

Problemi ed errori installazione pacchetti: apt-get

Per quanto riguarda i problemi con i pacchetti abbiamo visto che è possibile provare a riparare i pacchetti danneggiati con:

sudo dpkg --configure -a

Inoltre che è possibile controllare e risolvere errori o dipendenze dipendenze non soddisfatte dei pacchetti con:

sudo apt-get check 
sudo apt-get -f install
Reading package lists... Error!
E: Encountered a section with no Package: header
E: Problem with MergeList /var/lib/apt/lists/security.ubuntu.com_ubuntu_dists_natty-security_restricted_binary-i386_Packages
E: The package lists or status file could not be parsed or opened.

Si può provare a risolvere usando :

sudo rm /var/lib/apt/lists/* -vf
sudo apt-get update

Centos

yum install package
yum remove package
yum update

Indicatore di presenza con domoticz Iphone/Android

Contenuto di uno script crontab per il riavvio ogni 10 minuti

*/10 * * * *  /home/pi/domoticz/scripts/check_device_online.py 192.168.30.27 47 10 2700 ‘ per Iphone5

*/10 * * * *  /home/pi/domoticz/scripts/check_device_online.py 192.168.30.37 48 10 120 ‘ per Android

la sintassi è

*/10 * * * * /home/pi/domoticz/scripts/nome_script.py IP_:address_ipv4  nr_idx_domoticz nr_secondi nr_secondi_di_cambio_stato

COPIA DA QUI—- LO SCRIPT check_device_online.py RICORDATI I PERMESSI

#!/usr/bin/python
#   Title: check_device_online.py
#   Author: Chopper_Rob
#   Date: 25-02-2015
#   Info: Checks the presence of the given device on the network and reports back to domoticz
#   URL : https://www.chopperrob.nl/domoticz/5-report-devices-online-status-to-domoticz
#   Version : 1.6.2

import sys
import datetime
import time
import os
import subprocess
import urllib2
import json
import base64

# Settings for the domoticz server
domoticzserver=”192.168.30.23:8080″
domoticzusername = “”
domoticzpassword = “”
domoticzpasscode = “”

# If enabled. The script will log to the file _.log
# Logging to file only happens after the check for other instances, before that it only prints to screen.
log_to_file = False

# The script supports two types to check if another instance of the script is running.
# One will use the ps command, but this does not work on all machine (Synology has problems)
# The other option is to create a pid file named _.pid. The script will update the timestamp
# every interval. If a new instance of the script spawns it will check the age of the pid file.
# If the file doesn’t exist or it is older then 3 * Interval it will keep running, otherwise is stops.
# Please chose the option you want to use “ps” or “pid”, if this option is kept empty it will not check and just run.
check_for_instances = “pid”

# DO NOT CHANGE BEYOND THIS LINE
if len(sys.argv) != 5 :
print (“Not enough parameters. Needs %Host %Switchid %Interval %Cooldownperiod.”)
sys.exit(0)

device=sys.argv[1]
switchid=sys.argv[2]
interval=sys.argv[3]
cooldownperiod=sys.argv[4]
previousstate=-1
lastsuccess=datetime.datetime.now()
lastreported=-1
base64string = base64.encodestring(‘%s:%s’ % (domoticzusername, domoticzpassword)).replace(‘\n’, ”)
domoticzurl = ‘http://’+domoticzserver+’/json.htm?type=devices&filter=all&used=true&order=Name’

if check_for_instances.lower() == “pid”:
pidfile = sys.argv[0] + ‘_’ + sys.argv[1] + ‘.pid’
if os.path.isfile( pidfile ):
print datetime.datetime.now().strftime(“%H:%M:%S”) + “- pid file exists”
if (time.time() – os.path.getmtime(pidfile)) < (float(interval) * 3):
print datetime.datetime.now().strftime(“%H:%M:%S”) + “- script seems to be still running, exiting”
print datetime.datetime.now().strftime(“%H:%M:%S”) + “- If this is not correct, please delete file ” + pidfile
sys.exit(0)
else:
print datetime.datetime.now().strftime(“%H:%M:%S”) + “- Seems to be an old file, ignoring.”
else:
open(pidfile, ‘w’).close()

if check_for_instances.lower() == “ps”:
if int(subprocess.check_output(‘ps x | grep \” + sys.argv[0] + ‘ ‘ + sys.argv[1] + ‘\’ | grep -cv grep’, shell=True)) > 2 :
print (datetime.datetime.now().strftime(“%H:%M:%S”) + “- script already running. exiting.”)
sys.exit(0)

def log(message):
print message
if log_to_file == True:
logfile = open(sys.argv[0] + ‘_’ + sys.argv[1] + ‘.log’, “a”)
logfile.write(message + “\n”)
logfile.close()

def domoticzstatus ():
json_object = json.loads(domoticzrequest(domoticzurl))
status = 0
switchfound = False
if json_object[“status”] == “OK”:
for i, v in enumerate(json_object[“result”]):
if json_object[“result”][i][“idx”] == switchid:
switchfound = True
if json_object[“result”][i][“Status”] == “On”:
status = 1
if json_object[“result”][i][“Status”] == “Off”:
status = 0
if switchfound == False: print (datetime.datetime.now().strftime(“%H:%M:%S”) + “- Error. Could not find switch idx in Domoticz response. Defaulting to switch off.”)
return status

def domoticzrequest (url):
request = urllib2.Request(url)
request.add_header(“Authorization”, “Basic %s” % base64string)
response = urllib2.urlopen(request)
return response.read()

log (datetime.datetime.now().strftime(“%H:%M:%S”) + “- script started.”)

lastreported = domoticzstatus()
if lastreported == 1 :
log (datetime.datetime.now().strftime(“%H:%M:%S”) + “- according to domoticz, ” + device + ” is online”)
if lastreported == 0 :
log (datetime.datetime.now().strftime(“%H:%M:%S”) + “- according to domoticz, ” + device + ” is offline”)

while 1==1:
# currentstate = subprocess.call(‘ping -q -c1 -W 1 ‘+ device + ‘ > /dev/null’, shell=True)
currentstate = subprocess.call(‘sudo arping -q -c1 -W 1 ‘+ device + ‘ > /dev/null’, shell=True)

if currentstate == 0 : lastsuccess=datetime.datetime.now()
if currentstate == 0 and currentstate != previousstate and lastreported == 1 :
log (datetime.datetime.now().strftime(“%H:%M:%S”) + “- ” + device + ” online, no need to tell domoticz”)
if currentstate == 0 and currentstate != previousstate and lastreported != 1 :
if domoticzstatus() == 0 :
log (datetime.datetime.now().strftime(“%H:%M:%S”) + “- ” + device + ” online, tell domoticz it’s back”)
domoticzrequest(“http://” + domoticzserver + “/json.htm?type=command&param=switchlight&idx=” + switchid + “&switchcmd=On&level=0” + “&passcode=” + domoticzpasscode)
else:
log (datetime.datetime.now().strftime(“%H:%M:%S”) + “- ” + device + ” online, but domoticz already knew”)
lastreported=1

if currentstate == 1 and currentstate != previousstate :
log (datetime.datetime.now().strftime(“%H:%M:%S”) + “- ” + device + ” offline, waiting for it to come back”)

if currentstate == 1 and (datetime.datetime.now()-lastsuccess).total_seconds() > float(cooldownperiod) and lastreported != 0 :
if domoticzstatus() == 1 :
log (datetime.datetime.now().strftime(“%H:%M:%S”) + “- ” + device + ” offline, tell domoticz it’s gone”)
domoticzrequest(“http://” + domoticzserver + “/json.htm?type=command&param=switchlight&idx=” + switchid + “&switchcmd=Off&level=0” + “&passcode=” + domoticzpasscode)
else:
log (datetime.datetime.now().strftime(“%H:%M:%S”) + “- ” + device + ” offline, but domoticz already knew”)
lastreported=0

time.sleep (float(interval))

previousstate=currentstate
if check_for_instances.lower() == “pid”: open(pidfile, ‘w’).close()

Crontab su Raspberry appunti Rasbian linux

Raspberry Pi – CronTab e CronJob –

Il CronTab invece è un file testuale che contiene proprio la lista di comandi che verranno eseguiti da Cron. Si trova in /etc.

Ogni utente sul sistema ha un file crontab. Esiste persino una root crontab per i task che richiedono privilegi amministrativi.
Usare Cron

Per usare Cron, basta aprire il terminale e dare il comando:

crontab -e

si accederà al file che appartiene all’utente che ha dato il comando sul terminale.

Se vogliamo impostare dei task con privilegi amministrativi dovremmo accedere al crontab come utenti root:

sudo crontab -e

Aggiunto un task possiamo salvare il file. Le sezioni che compongono una entry nel crontab sono spiegate di seguito:

Sezioni Crontab

Ognuna di queste “sezioni” è separata da uno spazio, con la sezione finale con uno o più spazi all’interno. Nessuno spazio è permesso all’interno della Sezione 1-5, solo fra di essi. Le sezioni 1-5 vengono usate per indicare quando e quanto spesso si vuole che venga eseguito il comando. Questo è un esempio di cron job:

10 09 1 1 1 /usr/bin/cartella/comando

Con le sezioni rispettivamente a indicare:
MINUTI (0-59)
ORE (0-23, dove 0 sono le 24)
GIORNO (1-31)
MESE (1-12)
GIORNO DELLA SETTIMANA (0-6, dove 0 e’ la domenica)

SINTASSI
minuti (0-59), ore (0-23, 0 = mezzanotte), giorno (1-31), mese (1-12), giorno della settimana (0-6, 0 = domenica), Comando.

L’esempio mostrato sopra in particolare fa in modo che il comando venga eseguito Il 1 Gennaio, più ogni Lunedì di gennaio, alle 9:10 di mattina.
Un ulteriore simbolo (* asterisco) può essere usato in ogni istanza per indicare “ogni”. Ad esempio:

01 06 * * * /usr/bin/cartella/comando

Il comando sopra viene eseguito ogni giorno di ogni mese alle 6:01 di mattina.
Altre impostazioni più sofisticate possono essere generate utilizzando virgole e trattini.

Il comando specificato è sempre meglio includerlo con il percorso completo all’eseguibile. Per conoscere il percorso di un comando è sufficiente nel terminale, digitare prima del comando la parola which ad esempio in questo modo:

which ls

Il cronjob impostato nella crontab inizierà a girare non appena verranno salvate le modifiche alla crontab.

Un altro esempio di cronjob potrebbe essere questo:

*/30 * * * * curl http://roccomusolino.com/directory/update.php

Che fa in modo che ogni 30 minuti venga effettuata una richiesta con curl ad un certo script.
CronTab Avanzata

La crontab vista sopra è una crontab per gli utenti. Ogni crontab è associata ad un utente. Ma ci sono altri tipi di crontab, che fanno uso di stringhe speciali, “abbreviazioni” quali:

@reboot -> Esegui una volta, ad ogni avvio.
@yearly -> Esegui una volta all’anno, equivale a “0 0 1 1 *”.
@annually -> (Uguale a @yearly).
@monthly -> Esegui una volta al mese, “0 0 1 * *”.
@weekly -> Esegui una volta la settimana, “0 0 * * 0”.
@daily -> Esegui una volta al giorno, “0 0 * * *”.
@midnight -> (Uguale a @daily).
@hourly -> Esegui una volta ogni ora, “0 * * * *”.

Ad esempio:

@reboot python /home/pi/MyScript.py &

esegue lo script MyScript.py ogni volta che il sistema si avvia.

Questo vale per qualsiasi sistema Debian-based. Quindi se avete Raspbian su Raspberry Pi, potete automatizzare qualsiasi compito e task in questa maniera.

GRAZIE a https://hackerstribe.com per l’articolo

Errore installazione VMware vers. 12.x linux ubuntu

Se si prova ad installare VMware vers. 12.x sotto linux Ubuntu 16.10 si ottiene l’errore:

Gtk-WARNING **: Failed to load module “libcanberra-gtk-module.so”: libcanberra-gtk-module.so: cannot open shared object file: No such file or directory

per superare basta creare il link simbolico, naturalmente deve essere installato il seguente pacchetto:

sudo apt install libcanberra-dev

ricordatevi di dare

sudo ldconfig

e creare il link simbolico

sudo ln -s /usr/lib/x86_64-linux-gnu/gtk-2.0/modules/libcanberra-gtk-module.so /usr/lib/libcanberra-gtk-module.so

 

ERRORE SUL TEMA

Gtk-WARNING **: Impossibile trovare il motore del tema in module_path: «murrine»

apt-cache search murrine

e procedere alla installazione

sudo apt install murrine-themes