PHP7 – what’s new – I

Tipizzazione degli scalari

Facciamo una piccola introduzione. PHP è un linguaggio debolmente tipizzato, il che lo rende inviso a molti coders. Esso consente di fare cose strane del tipo

$a = '0';
$b = $a + 1; <---- questa è la cosa strana
$echo $b;
echo ':';
echo gettype($b)
// Output 1:integer

Ovvero l’operatore + (somma tra numeri interi/virgola mobile) è stato applicato ad una variabile $a che è string (che già è quanto meno esotico) e ad una costante che è integer per cui, a runtime, il compilatore ha deciso che il tipo del risultato $b andava conformato a quello della costante; prima di tutto ha effettuato il cast della stringa a intero ($a è “diventata” = 0, intero, non come stringa) e poi ha sommato la costante 1.

Alla fine il risultato è

// Output 1:integer

Effettivamente se non si fa attenzione a ciò che si scrive potremmo trovarci in situazioni inspiegabili e non abbiamo un compilatore che ci avverte (PHP è un linguaggio compilato ma la compilazione in bytecode viene fatta in modo silente dal motore Zend ogni volta che si lancia il programma dopo averlo modificato).

Nelle chiamate a funzione esiste la possibilità di forzare il tipo degli argomenti o in modo coattivo (coercive) oppure in modo stretto (strict).

Riprendiamo la funzione dell’articolo precedente e modifichiamo la lista dei parametri passati a runtime:

// 1.php - Coercive mode
function sumOfInts(int ...$ints) {
    return array_sum($ints);
}

var_dump(sumOfInts(2, '3', 4.1));

Possiamo specificare il tipo (un unico tipo per tutti i parametri) premettendolo ai tre puntini che precedono il nome dell’array; il tipo può essere SOLO uno dei seguenti:

  • int
  • string
  • float
  • bool

L’output di questo programma è

$ php 1.php 
/var/www/html/php7/1.php:10:
int(9)    

Nota che tutte le componenti dell’array sono state forzate a int, per cui 2+3+4=9. Questo comportamento è assunto per default, ovvero: in mancanza di indicazioni precise gli argomenti vengono forzati al tipo indicato.

Se si vuole che il blocco di codice invece utilizzi strettamente i tipi indicati, occorre istruire PHP attraverso una dichiarazione declare():

// Strict mode

declare(strict_types=1);

function sumOfInts(int ...$ints) {
    return array_sum($ints);
}

var_dump(sumOfInts(2, '3', 4.1));

l’output in questo caso evidenzia errori che riguardano solo l’errato tipo delle variabili in posizione 2 e 3:

PHP Fatal error:  Uncaught TypeError: Argument 2 passed to sumOfInts() must be of the type integer, string given, 
called in /var/www/html/php7/1.php on line 12 and defined in /var/www/html/php7/1.php:6
Stack trace:
#0 /var/www/html/php7/1.php(12): sumOfInts(2, '3', 4.1)
#1 {main}

Next TypeError: Argument 3 passed to sumOfInts() must be of the type integer, float given, 
called in /var/www/html/php7/1.php on line 12 and defined in /var/www/html/php7/1.php:6
Stack trace:
#0 /var/www/html/php7/1.php(12): sumOfInts(2, '3', 4.1)
#1 {main}
  thrown in /var/www/html/php7/1.php on line 6 

Se faccio girare questo script con una versione di PHP < 7 ho invece questo warning che riguarda la dichiarazione strict_types che è propria solo di PHP7:

[Tue Sep 25 11:43:12.440261 2018] [:error] [pid 4263] [client 127.0.0.1:52730] PHP Warning:  Unsupported declare 'strict_types' 
in /var/www/html/php7/1.php on line 3, referer: http://js/php7/

Tuttavia PHP 5.6 riconosce comunque l’impropria assegnazione di variabili non int a variabili dichiarate int e quindi fallisce:

[Tue Sep 25 11:43:12.441202 2018] [:error] [pid 4263] [client 127.0.0.1:52730] PHP Catchable fatal error:  Argument 1 
passed to sumOfInts() must be an instance of int, integer given, called in /var/www/html

Come si può vedere, c’è un sacco di roba che si può imparare dagli errori.

Diciamo senza malizia che l’effetto di PHP 7 in questo caso è di ammorbidire un già debole controllo sui tipi… Infatti se non imponiamo strict_types=1 lui fa una conversione al volo e fa funzionare un pezzo di codice che in PHP 5.6 non funzionerebbe! Tuttavia, se confrontiamo gli output di errore tra PHP 7 e PHP 5.6, vediamo che non si tratta più di un Catchable fatal error, ma di un errore di un nuovo tipo: TypeError (che vedremo nella prossima pillola).

PHP7 – what’s new

Oggi inizio a pubblicare delle pillole di PHP che riguardano le nuove caratteristiche introdotte nel PHP7. Seguono quelle enunciate nel sito php.net ma le commento e aggiungo qualche esempio.

Comincio con 

Passaggio di un numero indefinito di argomenti ad una funzione

Questo argomento non rapresenta una novità introdotta in PHP 7 ma è in qualche modo propedeutico ad altre novità. Generalmente una funzione ha un numero di argomenti definito in sede di dichiarazione. Ad esempio

// 3.php

function sum($a, $b) {
    return $a + $b;
}

echo sum(1, 2, 3); 

Qui però in sede di invocazione della funzione, passiamo più parametri di quelli dichiarati. Ciò che accade è che la somma venga eseguita solo sui primi due argomenti ma non c’è alcun errore sull’invocazione della API della funzione. Questo è quanto accade sia in PHP 7 che nelle versioni precedenti

$ php 3.php 
3

Come si vede, il programma ha sommato solo i primi due argomenti (1 e 2) e non il terzo (3). Questo comportamento è molto diverso da quello di altri linguaggi. Nella stessa situazione, ad esempio, un programma Python genera un errore:

#!/usr/bin/python
# 3.py

def sum(a,b):
   return a+b
   
print sum(1,2,3)

Output:

$ ./3.py 
Traceback (most recent call last):
  File "./3.py", line 6, in <module>
    print sum(1,2,3)
TypeError: sum() takes exactly 2 arguments (3 given)

Dunque PHP non da’ errore se la lista degli argomenti passati alla funzione differisce in numero da quella indicata nella dichiarazione, semplicemente ignora i parametri che in numero eccedono la definizione.

Dalla versione 5.6 tuttavia è stato introdotto un particolare operatore “” (detto “… token” nel sito di PHP) che consente di rendere dinamico il numero degli argomenti passati alla funzione che possono essere contenuti in un array di dimensione decisa a runtime.

// 4.php
function sumOfInts(int ...$ints) {
    return array_sum($ints);
}

var_dump(sumOfInts(1, 2));
var_dump(sumOfInts(2, 3, 4));

che fornisce l’output

$ php 4.php 
/var/www/html/php7/4.php:7:
int(3)
/var/www/html/php7/4.php:8:
int(9)

Pillole Linux: ancora grep

Eccoci ad un’altra puntata sul (potentissimo) programma grep GNU Regular Expression Parser – Analizzatore di Espressioni Regolari GNU (le altre puntate le trovate qui e qui).

L’output atteso di grep durante una ricerca può presentarci qualche sorpresa nel caso interpreti il file come binario

Se grep interpreta il file come binario e non come testo, anziché scrivere sullo standard output le linee contenenti le occorrenze del pattern cercato, scriverà un più laconico:

$ grep needle filename
Il file binario filename corrisponde

Però il file può effettivamente contenere del testo analizzabile, per cui possiamo forzare questo comportamento (quello di stampare le occorrenze della stringa needle) aggiungendo una opzione:

$ grep -a needle filename
 12:01:16.360		[VxmlLog.L1]         		LOG: logXML: message:  \volume=20   How do I find a needle inside a haystack?  \pause=0?

Come si vede, l’output di grep è quello atteso: la riga contenente la stringa cercata. L’opzione -a ha il significato di indicare a grep di trattare il file binario come se fosse un file di testo, come si legge dalla man page:

$ man grep
 -a, --text
        Process a binary file as if it were text; this is  
        equivalent to the --binary-files=text option.

Rimane la domanda: perché grep interpreta come binario un file che è evidentemente un file di testo (è un log di una applicazione)?

Il file in oggetto è codificato con la codifica ISO-8859-1 quindi non è un file tecnicamente di puro testo, visto che è stata operata la codifica detta per rappresentare caratteri oltre il settimo bit:

$ file filename
filename: ISO-8859 text, with very long lines, with CRLF line terminators

In ultima analisi è il programma stesso che stabilisce cosa considerare come testo o come non-testo. Infatti la direttiva POSIX è abbastanza generosa a riguardo:

A file that contains characters organized into zero or more lines. The lines do not contain NUL characters and none can exceed {LINE_MAX} bytes in length, including the <newline> character. Although POSIX.1-2017 does not distinguish between text files and binary files (see the ISO C standard), many utilities only produce predictable or meaningful output when operating on text files. The standard utilities that have such restrictions always specify "text files" in their STDIN or INPUT FILES sections

Anche se POSIX.1-2017 non distingue tra file di testo e file binari, molte utilities [come ad esempio grep] producono solamente un output attendibile o sensato quando operano su file di testo. Le utilities standard che hanno questo tipo di restrizione specificano sempre “file di testo” nel loro sezioni STIDIN o INPUT FILES.

Pillole Oracle – come recuperare lo script di definizione di una vista di un altro utente

Ho bisogno di rivedere il codice SQL di una vista di un utente diverso da quello con cui sono collegato al dbms Oracle.

Se ho privilegi di select sulla vista lo posso fare.

select * from ALL_VIEWS 
where owner='scott' 
and view_name='my_view'

L’oggetto ALL_VIEWS è una vista su tutte le viste visibili all’utente.

Pillole di Unicode

Unicode associa un numero univoco ad ogni carattere,
indipententemente dalla piattaforma,
indipententemente dal programma,
indipententemente dalla lingua.

 

I caratteri prima di Unicode

Fondamentalmente i computer gestiscono solo numeri. Essi memorizzano lettere ed altri caratteri assegnando un numero ad ognuno di essi. Prima che Unicode fosse inventato, esistevano centinaia di sistemi diversi, chiamati codifiche (encodings), per assegnare questi numeri. Queste prime codifiche di caratteri erano limitate e non contenevano abbastanza caratteri per coprire tutte le lingue del mondo. Anche per una singola lingua come l’inglese, un’unica codifica non era adeguata per descrivere tutte le lettere, segni di interpunzione e simboli tecnici di uso comune.

Le prime codifiche di caratteri inoltre confliggevano le une con le altre. Vale a dire, due codifiche potevano utilizzare lo stesso numero per due caratteri diversi o, viceversa, due numeri diversi per codificare lo stesso carattere. Quindi, quando i dati passavano da un computer all’altro o tra diversi sistemi di codifica, i dati rischiavano di venire corrotti.

I caratteri Unicode

Unicode ha cambiato tutto questo!

Lo Standard Unicode associa un numero univoco ad ogni carattere, indipendentemente dalla piattaforma, dal dispositivo, dall’applicazione o dalla lingua che vengono usati. È stato adottato da tutti i produttori di software moderni ed ora consente ai dati di essere trasportati attraverso molte differenti piattaforme, dispositivi e applicazioni senza corruzione. Il supporto di Unicode costituisce il fondamento per la rappresentazione di lingue e simboli in tutti i principali sistemi operativi, motori di ricerca, browser, computer portatili e smartphone – più Internet ed il World Wide Web (URLs, HTML, XML, CSS, JSON, etc.). Supportare Unicode è il modo migliore per implementare lo standard ISO/IEC 10646.

Lo standard ISO/IEC 10646

L’Insieme Universale di Caratteri Codificati [Universal Coded Character Set (UCS)] è un insieme standard di caratteri definiti dallo International Standard ISO/IEC 10646, Information technology — Universal Coded Character Set (UCS) (più successive modifiche), che è la base di di molte codifiche caratteri. L’ultima versione contiene oltre 136.000 caratteri astratti, ciascuno identificato con un nome non ambiguo e un numero intero detto il suo punto codice (code point). Questo standard ISO/IEC 10646 è manutenuto in congiunzione con lo standard Unicode ed entrambi sono identici codice per codice.

Ma ci sono delle differenze tra ISO/IEC 10646 e Standard Unicode e riguardano più l’ambito applicativo.

ISO/IEC 10646 è fondamentalmente una tabella, mentre Unicode si occupa anche delle regole da rispettare per eseguire il confronto di stringhe (collation), regole per la pronuncia dipendente dal contesto (text normalization) e altri aspetti.

[Wikipedia]

L’avvento dello Standard Unicode e la disponibilità di strumenti che lo supportano sono tra le più importanti tendenze della tecnologia software globale.

Sul Consorzio Unicode

Il consorzio Unicode è un’organizzazione no profit, esentasse negli USA (501(c)(3)) che è stata fondata per sviluppare, estendere e promuovere l’uso dello standard Unicode e i relativi standard di globalizzazione che specificano la rappresentazione del testo in prodotti software moderni e altri standard.

Il Consorzio viene supportato finanziariamente attraverso abbonamenti e donazioni. L’appartenenza al Consorzio Unicode è aperto alle organizzazioni e agli individui che, ovunque nel mondo, supportino lo standard Unicode e desiderino partecipare nella sua estensione ed implementazione. Tutti sono invitati a contribuire al supporto dell’importante lavoro del Consorzio facendo una donazione.

Maggiori informazionisi trovano sul sito di Unicode.

Pillole di MySQL: comportamento dei campi timestamp

mysqlNella dichiarazione di un campo di tipo timestamp viene per default abilitata la valorizzazione automatica all’istante corrente del campo quando inseriamo un nuovo record. Ad esempio, se in una tabella attivita abbiamo un campo data dichiarato come timestamp, quando inseriamo un nuovo record il campo verrà popolato anche senza la sua presenza esplicita nell’istruzione SQL. Supponiamo allora di avere questa tabella attivita così definita:

 

create table attivita1 (
   id int(10) auto_increment primary key,
   id_commessa int(10) not null,
   descrizione varchar(100) not null,
   data timestamp not null
);

Ora, se inserisco un record senza citare esplicitamente il campo data

insert into attivita (id_commessa, descrizione) values (123, 'Nuovo incarico');

nel campo data avrò il valore dell’istante in cui è stata eseguita l’istruzione (un po’ allo stesso modo con cui viene popolato un campo auto_increment).

Il problema (dal mio punto di vista per questa particolare applicazione) è che  lo stesso comportamento si verifica anche per un update:

update attività set id_commessa=321 where id=100

Anche il campo data, non esplicitamente citato nell’istruzione, cambierà. A volte ciò non è desiderabile. Per evitare questo comportamento dobbiamo modificare la tabella con una istruzione DDL:

ALTER TABLE attivita
CHANGE data 
data TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP

Così facendo non ho questo fastidioso (in questo caso) effetto collaterale.

Se non si dichiara esplicitamente il comportamento del default in fase di creazione, MySQL aggiungerà  automaticamente anche questa direttiva:

DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

che causerà il comportamento indesiderato durante l’aggiornamento.

 

 

Martorèo

È un vocabolo del dialetto veneto, almeno nella mia zona di origine che si situa nel baricentro tra le città di Venezia, Padova e Treviso. Amici della provincia di Treviso mi segnalano che da quelle parti verso la Pedemontana si chiami MazariòlMathariòl, pronunciato con il suono della theta greca (la fricativa dentale sorda dell’alfabeto fonetico internazionale, denotata con la lettera θ).

Questo termine di cui voglio parlare non è la versione dialettale della parola martorello, che si trova nel Dizionario della Crusca (ma non si trova nel Devoto-Oli, per esempio), il cui significato e uso sono del tutto estranei alla tradizione veneta. Si tratta invece del nome con cui ci si riferisce ad una specie di demone, o di folletto, che i contadini veneti ritenevano responsabile di scherzi ai loro danni, come ad esempio la sparizione di attrezzi di lavoro o di altri oggetti di uso quotidiano.

Nella costante commistione sincretistica esistente nella mia terra tra queste rappresentazioni pagane e il cattolicesimo, c’è chi per rimediare all’impossibilità di ritrovare le cose perdute si affidava a Sant’Antonio da Padova recitando i cosiddetti “Sequeri”, dal latino “Si quaeris” (se cerchi) che è l’incipit della preghiera “Si quæris miracula” [Fonte]. Miracolosamente l’oggetto cercato faceva la sua comparsa, di solito in un luogo in cui si poteva giurare di aver guardato più volte. Le mie nonne mi hanno assicurato, per esempio, che la cosa funzionava.

A parte la divertente circostanza che il termine query, che in Informatica si usa così abbondantemente per indicare l’interrogazione di un database, tragga origine proprio dall’equivalente del latino cercare,  e la presenza di demoni anche in informatica (sono, soprattutto in ambiente Unix quei programmi che sono in costante esecuzione per tutto il tempo di accensione della macchina e ai quali sono associati dei servizi in ascolto: web server, mail server eccetera), l’accezione che io ho dato al martoreo (lo scrivo in dialetto) è quella di bug del software insidioso e difficile da scovare.

Mi sono trovato molte volte infatti di fronte ad un malfunzionamento del software la cui causa è particolarmente difficile da individuare: se si legge il codice sembra che la sua esecuzione non debba portare al malfunzionamento presente in quel momento. Cioè sembra tutto corretto ma il programma sbaglia. Ecco, ho da tanti anni battezzato questa situazione con una locuzione tratta dalla mia tradizione contadina: è colpa del martorèo, il folletto che in qualche modo agisce su programmi e dati per creare un malfunzionamento. Non ho trovato nessun altro che usasse questo curioso vocabolo per descrivere un bug difficile, non so se considerarlo un mio conio. Però quando lo uso e lo spiego per la prima volta al mio uditorio, tutti rimangono molto divertiti dalla storia.

Installazione di due versioni di PHP + Apache

Ho la necessità di lavorare alternativamente con PHP 5.6 e PHP 7.2 per due clienti.

Siccome parto da PHP5.6,  occorre installare PHP7 e il modulo Apache per PHP7 e intervenire in configurazione per selezionare l’uno o l’altro a seconda del lavoro che devo fare.

  1. Installazione di PHP7.2:
    $ sudo apt-get install php7.2 php7.2-mysql php7.2-ldap php7.2-cli
    
    $ sudo apt-get --purge autoremove -y
  2. Installazione del modulo Apache per PHP
    $ sudo apt-get install -y libapache2-mod-php7.2
  3. attivazione dell’alternativa client php7.2
    $ sudo update-alternatives --set php /usr/bin/php7.2
    
    $ php -v
    
    PHP 7.2.5-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: May 5 2018 04:59:13) ( NTS )
    
    Copyright (c) 1997-2018 The PHP Group
    
    Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    
     with Zend OPcache v7.2.5-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
    
     with Xdebug v2.6.0, Copyright (c) 2002-2018, by Derick Rethans
  4. configuazione di Apapche perché utilizzi PHP7.2 anziché il 5.6
    $ sudo a2dismod php5.6
    
    $ sudo a2enmod php7.2
    
    $ service apache2 restart

 

That’s all folks

 

Upgrade Ubuntu da 15.04 a 16.04 LTS Dapper Drake

Ho aggiornato il mio Ubuntu 15.04 alla 16.04 LTS Dapper Drake, rimanendo in attesa dell’8 luglio per poter ulteriormente aggiornare alla 18.04 LTS Bionic Beaver

Sono successi alcuni inconvenienti, non gravissimi, che elenco:

MySQL non parte più.

In questo caso ho dovuto reinstallare mysql-server e aggiornare il file di configurazione di Apparmor che non consentiva a MySQL di accedere a determinate directory.
Il punto di partenza è l’errore che si manifesta quando andiamo a lanciare mysqld (per comodità lavoro come root):

# service mysql start

Job for mysql.service failed because the control process exited with error code. See "systemctl status mysql.service" and "journalctl -xe" for details.

Qui occorre fare diagnosi come indicato nel messaggio d’errore:

# journalctl -xe
-- L'unità mysql.service ha iniziato la fase di avvio.
mag 08 10:37:50 jsbach audit[11686]: AVC apparmor="DENIED" operation="open" profile="/usr/sbin/mysqld" name="/proc/11686/status" pid=11686 comm="mysqld" requested_mask="r" denied_mask="r" fsuid=120 ouid=120
mag 08 10:37:50 jsbach audit[11686]: AVC apparmor="DENIED" operation="open" profile="/usr/sbin/mysqld" name="/sys/devices/system/node/" pid=11686 comm="mysqld" requested_mask="r" denied_mask="r" fsuid=120 o
mag 08 10:37:50 jsbach audit[11686]: AVC apparmor="DENIED" operation="open" profile="/usr/sbin/mysqld" name="/proc/11686/status" pid=11686 comm="mysqld" requested_mask="r" denied_mask="r" fsuid=120 ouid=120
mag 08 10:37:50 jsbach kernel: audit: type=1400 audit(1525768670.619:280): apparmor="DENIED" operation="open" profile="/usr/sbin/mysqld" name="/proc/11686/status" pid=11686 comm="mysqld" requested_mask="r" 
mag 08 10:37:50 jsbach kernel: audit: type=1400 audit(1525768670.619:281): apparmor="DENIED" operation="open" profile="/usr/sbin/mysqld" name="/sys/devices/system/node/" pid=11686 comm="mysqld" requested_ma
mag 08 10:37:50 jsbach kernel: audit: type=1400 audit(1525768670.619:282): apparmor="DENIED" operation="open" profile="/usr/sbin/mysqld" name="/proc/11686/status" pid=11686 comm="mysqld" requested_mask="r" 
mag 08 10:37:50 jsbach audit[11686]: AVC apparmor="DENIED" operation="mknod" profile="/usr/sbin/mysqld" name="/run/mysqld/mysqld.sock.lock" pid=11686 comm="mysqld" requested_mask="c" denied_mask="c" fsuid=1
mag 08 10:37:50 jsbach kernel: audit: type=1400 audit(1525768670.971:283): apparmor="DENIED" operation="mknod" profile="/usr/sbin/mysqld" name="/run/mysqld/mysqld.sock.lock" pid=11686 comm="mysqld" requeste
mag 08 10:37:52 jsbach systemd[1]: mysql.service: Main process exited, code=exited, status=1/FAILURE
mag 08 10:38:06 jsbach audit[11748]: AVC apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/sbin/mysqld" pid=11748 comm="apparmor_parser"
mag 08 10:38:06 jsbach kernel: audit: type=1400 audit(1525768686.555:284): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/sbin/mysqld" pid=11748 comm="apparmor_parser"
mag 08 10:38:20 jsbach systemd[1]: Failed to start MySQL Community Server.

-- Subject: L'unità mysql.service è fallita

Ciò che occorre fare è informare apparmor perché non blocchi l’accesso alle directory indicate nel file di log: scorrendo la slide sopra ho evidenziato alcuni file che apparmor non permette a mysql di toccare; quindi si procede così:

# gedit /etc/apparmor.d/usr.sbin.mysqld

si aggiungono queste righe al file, stando attenti a scrivere all’interno dell parentesi graffe {}:

 /var/run/mysqld/mysqld.sock.lock rw,
 /run/mysqld/mysqld.sock.lock rw,
 /tmp/** rwk,
 /sys/devices/system/node/* r,
 /proc/* r,

Sia /sys/device che /proc/ hanno un asterisco perché il file che viene bloccato cambia ad ogni avvio.
Dopodiché si si fa un reload di apparmor.d:

# apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld

Ora si può riavviare mysqld:

# service mysql start
# mysql -u root -proot01
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.22-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> ^DBye

E’ sparito PHP

Nel senso che Apache non attiva il modulo interprete di PHP.

Le pagine contenti PHP mi vengono servite così come sono, col codice e tutto, come se fossero un documento di testo o html.

In questo caso aggiungo il modulo mod_php5.6

# apt-get install libapache2-mod-php5.6

e lo attivo tramite /etc/apache2/mods-available/:

less /etc/apache2/mods-available/php5.6.load 
# Depends: mpm_prefork
LoadModule php5_module /usr/lib/apache2/modules/libphp5.6.so

È possibile anche installare e attivare il modulo PHP7, ma ovviamente occorre avviarne solo uno (quindi nei /mods-available/ si possono preparare varie versioni di PHP e poi creare il link ad uno solo di questi nella directory /mods-enabled/). Fatto questo si può verificare la correttezza della configurazione e finalmente avviare Apache:

# apache2ctl configtest 
Syntax OK
# service apache2 start
#

Due parole su AppArmor

Dal Wiki abbiamo la definizione pulita:

AppArmor è un’implementazione del «Linux Security Module» per il controllo degli accessi vincolante basato sul nome. AppArmor racchiude individualmente i programmi in un insieme di file e capacità posix 1003.1e draft.

È un sistema di sicurezza MAC (Mandatory Access Control) per Linux e serve per integrare ed estendere le politiche di sicurezza di Linux sui programmi in esecuzione ad un livello applicazione (quindi AppArmor fa la guardia al comporatmento delle applicazioni stando sopra al sistema operativo allo stesso loivello dell’applicazione da controllare).

Il controllo si effettua mediante creazione di profili, che sono dei file descrittivi che di solito vengono salvati nella directory

$ ll /etc/apparmor.d/
...
-rw-r--r-- 1 root root 8467 apr 4 13:58 usr.bin.firefox
-rw-r--r-- 1 root root 38551 dic 20 2016 usr.bin.webbrowser-app
-rw-r--r-- 1 root root 21143 apr 11 15:11 usr.lib.snapd.snap-confine.real
-rw-r--r-- 1 root root 8084 lug 27 2015 usr.lib.telepathy
-rw-r--r-- 1 root root 469 set 14 2015 usr.sbin.cups-browsed
-rw-r--r-- 1 root root 5119 ott 8 2015 usr.sbin.cupsd
-rw-r--r-- 1 root root 546 set 18 2015 usr.sbin.ippusbxd
-rw-r--r-- 1 root root 1264 mag 8 10:48 usr.sbin.mysqld
...

Nell’esempio sopra (mySql) apparmor.d bloccava l’accesso di mysqld a determinate directory al di là dell’accessibilità concessa dal sistema operativo.

Bibliografia

Ho trovato utili vari siti, tra cui:

https://linuxconfig.org/how-to-upgrade-to-ubuntu-18-04-lts-bionic-beaver

 

Pillole LaTeX: aggiungere un package

LaTeX è il sistema di redazione di documenti scientifici più popolare da ormai più di 20 anni.

Le potenzialità sono state ampliate nel tempo fornendo dei componenti terzi che sono agganciabili al motore di LaTeX eseguando l’installazione di un pacchetto (package)

Un esempio: il package Tikz-feynman, che aggiunge la possibilità di disegnare diagrammi di Feynman.

Istruzioni

  1. Scaricare il package (per esempio del sito dello sviluppatore Joshua Ellis)
  2. estrarre il pagkage (un tarball tar.gz) sotto il path di installazione di LaTeX: nel mio caso è
    /usr/share/texlive/texmf-dist/tex/latex
  3. aggiornare il database dei package del motore latex (necessario se abbiamo installato sotto /sr/bin… che è una installazione globale – cioè accessibile a tutti gli utenti della macchina
    $ sudo mktexlsr
    mktexlsr: Updating /usr/local/share/texmf/ls-R…
    mktexlsr: Updating /var/lib/texmf/ls-R-TEXLIVEDIST…
    mktexlsr: Updating /var/lib/texmf/ls-R-TEXMFMAIN…
    mktexlsr: Updating /var/lib/texmf/ls-R…
    mktexlsr: Done.
  4. Have fun:  nel preambolo sorgente LaTeX, includere il package:
    \usepackage{tikz}
    \usepackage[compat=1.1.0]{tikz-feynman}

Il programma

\feynmandiagram [horizontal=a to b] {
   i1 -- [fermion] a -- [fermion] i2,
   a -- [photon] b,
   f1 -- [fermion] b -- [fermion] f2,
};
produrrà questo diagramma di Feynman