# Pour les scripts : c'est ici

**URL:** <https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820>\
**Category:** Trucs et Astuces\
**Created:** [Février 20, 2016, 12:53 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820 "2016-02-20T12:53:11Z")\
**Posts on this page:** 20\
**Page:** 15

<div class="post-metadata">

**Author:** ![M3t4linux](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/5daacb/32.png) [@M3t4linux](https://www.debian-fr.org/u/M3t4linux)\
**Post date:** [Février 21, 2016, 11:20 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/281 "2016-02-21T11:20:09Z")

</div>

[Un script bash qui affiche de la neige!!](http://www.tux-planet.fr/un-script-bash-pour-afficher-de-la-neige-dans-son-terminal/)

---

<div class="post-metadata">

**Author:** ![Rantanplan\_aussi](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/r/258eb7/32.png) [@Rantanplan\_aussi](https://www.debian-fr.org/u/Rantanplan_aussi)\
**Post date:** [Février 21, 2016, 11:21 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/282 "2016-02-21T11:21:03Z")

</div>

Marrant 😉

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 11:44 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/284 "2016-02-21T11:44:49Z")

</div>

Je viens de l’essayer (avec la sous commande update), il est vraiment pas mal (qu’est ce que j’aime avoir un terminal coloré !).  
Je me demande si je ne vais pas intégrer mon apt-search directement de dans (ça me donnerais l’occasion de faire du ruby pour une fois).

Merci pour le partage.

---

<div class="post-metadata">

**Author:** ![ptitdernier](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/p/45deac/32.png) [@ptitdernier](https://www.debian-fr.org/u/ptitdernier)\
**Post date:** [Février 21, 2016, 11:45 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/285 "2016-02-21T11:45:07Z")

</div>

Ma petite contribution : un menu de sauvegardes avec options sur serveur, freebox V6 et disque USB  
il est bien sur adapté à mes besoins mais je pense qu’il est facilement adaptable par chacun d’entre nous  
il souffre bien sur de certaines imperfections car je ne suis pas un pro du script et il me reste un problème important : vérifier qu’un autre utilisateur n’est pas actif sur le serveur avant de le mettre en veille

Je me suis bien amusé à le créer tout en apprenant le script shell et les critiques seront les bienvenues !

[code]#!/bin/bash  
#--------------------------------------------------------------------------------------

# script “sauvegardes”

# 

# Sauvegarde des données sur Freebox server V6 et serveur maison.

# peut être utilisé par plusieurs différents utilisateurs sur une machine et par plusieurs

# postes sur le réseau.

# 

# Lance un menu de choix de sauvegardes ; ce menu désactive les actions déjà réalisées.

# 

# Utilise rsync avec ssh pour synchroniser les fichiers sur le serveur et lftp pour

# la même chose sur freebox.

# Les données sont toutes copiées sur le serveur maison et pour certaines

# aussi sur la freebox ; certaines sont aussi exportées sur un disque USB

# 

# Utilise plusieurs “modules” ou fichiers de conf ; j’ai créé un dossier bin sur $HOME

# dans lequel j’ai mis tous mes scripts et fichiers de conf

# 

# - serveur.rc : variables globales copiées dans /etc/environment

# - controle\_log.h : vérifie que l’on n’est pas root

# - serveur\_on : si le serveur est en veille =\> réveil

# - sv-exclude-$user : fichier de config du user en cours donnant le liste des

# exclusions/inclusions de rsync. Il sert à la sauvegardes des données personnelles

# de chaque user

# - sv-ftp-$user : dossiers médias à synchroniser sur la freebox

# - sv-media-$user : dossiers médias à synchroniser sur le serveur

# 

# la commande doit être lancée en console avec le user personnel (pas de su)

#--------------------------------------------------------------------------------------

# vérification disponibilité du serveur et réveil si nécessaire

source bin/serveur\_on

#\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

# données générales

#\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
f\_freebox=“Disque dur” # nom du disque interne de la freebox  
cible=“ftp://freebox:xxxxx@mafreebox.freebox.fr”

rouge=’\e[31m’ # quelques zoulies couleur pour égayer le shell  
bold=’\e[01m’  
fdgris=’\e[1;47m’  
neutre=’\e[0m’

#----- menu --------------  
n\_choix[0]="Quitter"  
n\_choix[1]="Données personnelles"  
n\_choix[2]="Fichiers multimédia"  
n\_choix[3]="Films sur disque USB"  
n\_choix[4]="Utilitaires"  
n\_choix[5]=“VirtualBox VMs”

declare -a r\_choix=(0 0 0 0 0 0) # choix réalisé != 0

if [$USER == ‘michel’] ; then # quelques option pas pour tout le monde :=}  
nb=5  
else  
nb=2  
fi

while : ; do  
while : ;do  
clear  
echo -e "\n\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*"  
echo "\* Utilitaire de sauvegarde \*"  
echo -e "\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n"  
echo  
for ((i=0; i\<=nb; i++)) ; do # écriture du menu de choix  
echo -e “\t”$i’) '${n\_choix[i]}  
done  
echo  
read -p "faites votre choix ( 0 à $nb ) : " choix  
case $choix in  
0)  
read -p "Voulez-vous vraiment quitter (o/n) ? : " r  
if [$r == ‘o’] ; then  
exit 0  
fi  
continue  
;;  
[1-$nb])  
if [${r\_choix[$choix]} == 1 ]; then  
echo -e “\n”${rouge}${bold}“Cette sauvegarde a déjà été réalisée”${neutre}  
read  
continue  
fi  
break  
;;  
\*)  
echo -e “\n”${rouge}${bold}“Choix incorrect”${neutre}  
read  
esac

```
done

read -p "Confirmation synchronisation de ${n_choix[$choix]} (o/n) : ? " r
if [$r != 'o'] ; then
	continue
fi

clear
case $choix in
	1) # synchronisation des données personnelles
		echo -e "\nDémarrage de la synchronisation des données personnelles"
		rsync -ruptv --delete --delete-excluded --backup --backup-dir=../Backup/$USER --exclude-from=$HOME/bin/sv-exclude-$USER $HOME/ $LOG@$SERVEUR:Public/$USER
	;;

	2) # sauvegarde des multimédias
		echo -e "\nDémarrage de la sauvegarde des Médias"

		echo -e "\nSauvegarde des Médias vers le serveur"
		while read ligne ; do # lecture du fichier liste des répertoires
			if [${ligne:0:1} != '#'] ; then
				origine=${ligne%=>*}
				destination=${ligne##*=>}
				echo -e "\nSauvegarde de $origine vers $destination du serveur"
				rsync -ruptv $HOME/$origine/ $LOG@$SERVEUR:$destination
			fi
		done < $HOME/bin/sv-medias-$USER

		while read ligne ; do # lecture du fichier liste des répertoires
			if [${ligne:0:1} != '#'] ; then
				origine=${ligne%=>*}
				destination=${ligne##*=>}
				echo -e "\nSauvegarde de $origine vers $destination de la freebox"
				lftp $cible -e "mirror -R $origine -x .mediaartlocal '$f_freebox'/'$destination' ; quit"
			fi
		done < $HOME/bin/sv-ftp-$USER
	;;

	3) # synchronisation des Films sur un disque externe
		echo -e "\n\nSynchronisation des films sur disque USB"
		echo " ***************************************************************************"
		echo "* Vérifier que le disque USB de destination est monté et taper une touche *"
		echo " ***************************************************************************"
		read -s -n 1 r

		echo -e "\nChoisir le support de destination\n"

		ls /media -1 --quoting-style=escape > tmp # récupération des supports externes
		i=0
		while read ligne[$i] ; do
			ligne[$i]="/media/"${ligne[$i]}
			(( i++ ))
			echo $i"- "${ligne[$i-1]}
		done < tmp

		usb=0
		echo -n "Choisir le média entre 1 et $i : "
		while (( $usb < 1 || $usb > $i )) ;	do
			read -n 1 usb
			echo -n -e "\b"
		done

		MediaDestination=${ligne[$usb-1]} # emplacement de destination des Films
		echo -n "Sauvegarde vers $MediaDestination (o/n) ? : "
		read r
		if [[$r != o]] ; then
			exit 1
		fi
		echo

		rm -f tmp
		MediaOrigine="$HOME/Films" # emplacement des sources des Films
		rsync -ruptv $MediaOrigine/ $MediaDestination/
		if [[$? != 0]]; then
			echo -e "\nErreur Sauvegarde"
			read -n 1 r
		fi
	;;

	4) # sauvegarde des utilitaires
		echo -e "\n\nSynchronisation de Utilitaires"
		rsync -ruptv --delete --backup --backup-dir=../Backup/Utilitaires $HOME/Utilitaires/ $LOG@$SERVEUR:Public/Utilitaires
	;;

	5) # sauvegarde des données VirtualBox
		echo -e "\n\nSynchronisation de VirtualBox"
		rsync -ruptv --delete --backup --backup-dir=../Backup/Utilitaires $HOME/"VirtualBox VMs"/ $LOG@$SERVEUR:Public/"VirtualBox\ VMs"

	;;
esac
n_choix[$choix]=${rouge}${bold}${fdgris}${n_choix[$choix]}" ......Réalisé"${neutre}
r_choix[$choix]=1

```

done

# si le serveur était en veille au démarrage de la sauvegarde, remise en veille

# $veille est positionnée par serveur\_on

# off = serveur actif

# on = serveur en veille

if [$veille == ‘on’]; then  
echo "Mise en veille du serveur…"  
source bin/serveur\_off  
fi  
[/code]  
suite …

[code]# serveur.rc

# 

# paramètres du serveur

# ces valeurs sont utilisées par les scripts concernant le serveur

# copier ce fichier dans /etc/environment et ces valeurs resteront

# accessibles dans toutes les sessions bash

# su -c ‘cat serveur.rc \>\> /etc/environment’

# 

# SERVEUR adresse IP du serveur

# MAC= adresse MAC de la carte eternet du serveur

# SV\_MEDIAS= répertoire médias du serveur exporté par nfs4

# SV\_ADMIN= répertoire home du média exporté par nfs4

# LOG= nom du user du serveur

# BLOC= taille de rsize et wsize de nfs

# veille état du serveur au début du script (on=\>en veille)

SERVEUR='[192.168.xxx.xxx](http://192.168.xxx.xxx)’  
MAC='xx:xx:xx:xx:xx:xx’  
SV\_MEDIAS='MEDIAS’  
SV\_ADMIN='ADMIN’  
LOG='administrateur’  
BLOC='32768’  
veille=‘off’  
[/code]  
et encore

[code]#!/bin/bash  
#--------------------------------------------------------------------------------------

# controle\_log.h

# Vérification du log

# Si logué en user =\> OK et passage en $HOME

# Si logué autre que user =\> sortie en erreur 1

#-------------------------------------------------------------------------------------

# contrôle du log

if [$(logname) != $USER]; then # console loguée autrement que par user ?  
echo "ATTENTION !!! "  
echo "La console n’est pas loguée en ---- $(logname) ----"  
echo "Corriger et recommencer"  
read -p "Appuyer sur ‘enter’"  
exit 1  
else  
cd $HOME  
fi

[/code]

[code]#!/bin/bash  
#\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

# script “serveur\_on”

# teste le disponibilité du serveur

# serveur.rc contient les paramètres (=\> /etc/environnement)

# si en veille, tente de le réveiller et positionne $veille = ‘on’

# autrement $veille = ‘off’

# la commande showmount vérifie que nfs est bien lancé

#\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

# contrôle du log

source /home/$(logname)/bin/controle\_log.h # vérification logué en $user

maxtest=8 # nombre de tentatives réveil serveur

# teste la disponibilité du serveur

echo "Test disponibilité du serveur à l’IP : "$SERVEUR

if ( ! ping -c 1 $SERVEUR ) ; then  
veille="on"  
echo -e "\nLe serveur est certainement en veille. Tentative de réveil…\n"  
wakeonlan $MAC # paquet magique de réveil

```
test=1
echo "test n° $test ..."
while !(/sbin/showmount -e $SERVEUR) && (($test <= $maxtest))
do
	(( test++ ))
	echo "test n° $test ..."
done

if (($test > $maxtest)) ; then
	read -p "Serveur indisponible"
	exit 1 # code d'erreur
fi

```

else  
veille="off"  
fi  
[/code]

```auto
# sv-exclude-michel
Films/
Musique/
Téléchargements/
Utilitaires/
**VirtualBox**
Public/
Vidéos/
*/lost+found/
*/Cache/
+ .avidemux/
+ .barry/
+ .config/
+ .easytag/
+ .gconf/
+ .gconfd/
+ .icedove/
+ .local/
+ .mozilla/
+ .Skype/
+ .ssh/
+ .themes/
.*/
.*
```

[code]# sv-ftp-michel

# ‘répertoire origine’=\>‘répertoire destination’ sur freebox

Musique=\>Musiques[/code]

[code]# sv-media-michel

# ‘répertoire origine’=\>‘répertoire destination’ sur serveur maison

Musique=\>/DATA/Musique  
Films=\>/DATA/Films[/code]

---

<div class="post-metadata">

**Author:** ![thuban](https://www.debian-fr.org/user_avatar/www.debian-fr.org/thuban/32/4177_2.png) [@thuban](https://www.debian-fr.org/u/thuban)\
**Post date:** [Février 21, 2016, 12:49 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/286 "2016-02-21T12:49:22Z")

</div>

Remplir un baladeur de chansons aléatoires

[size=85]Souhaitant remplir mon baladeur par des chansons de façon aléatoire après avoir vu ce concept sur quelques sujet sur le net, j’ai écrit ce petit script en python (python3) qui fait l’affaire.

En effet, les autres solutions étaient en bash, perl, ou encore en python+appels système à gogo. Et ça ne me semblait pas très propre, ni ne fonctionnait.  
.[/size]  
Donc voici le script, que je vous invite à adapter ou corriger sans retenue!

Renseignez, avant tout usage, le dossier de destination à remplir de musiques (votre baladeur, ou autre), ainsi que le dossier contenant toutes vos musiques.

Important : attention aux noms de fichiers bizarre. Pour cela :

```auto
detox -r Musique/
```

Aperçu : image : rdmzic.png  
[![](http://pix.toile-libre.org/upload/thumb/1342730661.png)](http://pix.toile-libre.org/?img=1342730661.png)

Le script (modifié après discussion ci-dessous. Voir aussi la solution proposée par Misterfreez en zsh):

```auto
#!/usr/bin/env python
# -*- coding:Utf-8 -*- 
# Fichier: rdmzic.py
# Cree le 19 juil. 2012 20:55:03

"""

Auteur : thuban (thuban@singularity.fr)  
licence : GNU General Public Licence

Description :
    Script copiant des musiques sur un baladeur en
    choisissant aléatoirement parmis touts les
    fichiers musicaux présents dans un répertoire.

    /!\ Editez les variables correspondant à vos /!\
    /!\ dossiers sources et cibles. /!\
"""

import sys, os, random, shutil

musicBib = '/home/xavier/Musique' # Votre bibilothèque musicale
baladDir = '/media/baladeur/Music' # Là où on copie les musiques

extensions = ['.ogg','.mp3','.flac','.wma']

#----------------------------------------------------------------#
def dirOk():
    if not os.path.isdir(musicBib):
        print('On dirait qu\'il y a une erreur, le dossier {0} \
n\'existe pas ou n\'est pas accessible'\
              .format(musicBib))
        print('Veuillez préciser l\'emplacement de votre \
bibliothèque musicale dans le script, \
dans la variable musicBib au début du fichier.')
        sys.exit(1)
    elif not os.path.isdir(baladDir):
        print('On dirait qu\'il y a une erreur, le dossier {0} \
n\'existe pas ou n\'est pas accessible'\
              .format(baladDir))
        print('Veuillez préciser l\'emplacement de votre \
du dossier où sera copié les musiques, \
dans la variable baladDir au début du script.')
        sys.exit(1)

def restePlace(chanson):        
    '''Vérifie s'il reste de la place pour mettre la chanson
    sur le baladeur
    '''
    infos = os.statvfs(baladDir)
    libre = infos.f_bavail * infos.f_frsize
    taille = os.stat(chanson).st_size

    if (libre - taille) > 0:
        return(True)
    else:
        return(False)

def progressBar():
    '''affiche une barre de progression
    basée sur la place restante sur le
    media de destination
    '''
    infos = os.statvfs(baladDir)
    libre = infos.f_bavail * infos.f_frsize
    total = infos.f_frsize * infos.f_blocks

    bar = '=' * int((float(total - libre) / float(total) * 100))
    bar += '>'
    while len(bar) < 100:
        bar += '-'

    print(bar)

def main():
    
    dirOk()

    # On vide le répertoire cible
    for f in os.listdir(baladDir):
        os.remove(os.path.join(baladDir,f))

    # création de la liste des musiques disponibles
    musList = []
    for dirpath, dirnames, filenames in os.walk(musicBib):
        for f in filenames:
            if os.path.splitext(f)[1].lower() in extensions:
                m = os.path.join(dirpath,f)
                musList.append(m)

    # début de la copie
    while len(musList) != 0:
        # Choix d'une chanson au hasard
        chanson = random.choice(musList)
        musList.remove(chanson)
        if restePlace(chanson):

            print('On copie {0}\n'.format(chanson))
            progressBar()
            shutil.copy(chanson,baladDir)
            # pour un affichage plus chouette
            #print(chr(27) + "[2J")
            sys.stderr.write("\x1b[2J\x1b[H")

    print('\n')
    print('Et voilà, le dossier de destination est rempli de musiques!')
    print('\o/')
    
        

    return 0

if __name__ == ' __main__':
	main()

# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
```

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 12:49 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/287 "2016-02-21T12:49:26Z")

</div>

Excuse-moi mais :

```auto

```

N’est pas loin de ce que tu cherche a faire non ? Là où c’est sale c’est qu’il va tenter pour un tas de fichiers après que le lecteur soit pleins. Mais si on quitte le monde une ligne (et une petite optimisation) :

`set -e
mount_dir='/media/mon_lecteur'
for musique in $(print -l mydir/**/*.{ogg,mp3,flac,wma}(.) | shuf) ; do
    [-f "${mount_dir}/${musique##*/}"] || cp -v "${musique}" "${mount_dir}"
done`  
devrait être plus indiqué.

---

<div class="post-metadata">

**Author:** ![thuban](https://www.debian-fr.org/user_avatar/www.debian-fr.org/thuban/32/4177_2.png) [@thuban](https://www.debian-fr.org/u/thuban)\
**Post date:** [Février 21, 2016, 12:49 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/288 "2016-02-21T12:49:29Z")

</div>

[quote=“MisterFreez”]Excuse-moi mais :  
[/quote]  
Surtout pas! 🙂 Tiens, on dirait que je vais apprendre des trucs!

[quote=“MisterFreez”]

```auto

```

N’est pas loin de ce que tu cherche a faire non ? Là où c’est sale c’est qu’il va tenter pour un tas de fichiers après que le lecteur soit pleins. Mais si on quitte le monde une ligne (et une petite optimisation) :

`set -e
mount_dir='/media/mon_lecteur'
for musique in $(print -l mydir/**/*.{ogg,mp3,flac,wma}(.) | shuf) ; do
    [-f "${mount_dir}/${musique##*/}"] || cp -v "${musique}" "${mount_dir}"
done`  
devrait être plus indiqué.[/quote]  
Les trois quarts des commandes proposées, je ne les connaissait pas. (shuf, cpio…)  
Juste la fin, ça fait quoi exactement ça, si je puis me permettre ? :

```auto

```

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 12:49 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/289 "2016-02-21T12:49:31Z")

</div>

[quote=“thuban”][quote=“MisterFreez”]`set -e
mount_dir='/media/mon_lecteur'
for musique in $(print -l mydir/**/*.{ogg,mp3,flac,wma}(.) | shuf) ; do
    [-f "${mount_dir}/${musique##*/}"] || cp -v "${musique}" "${mount_dir}"
done`  
devrait être plus indiqué.[/quote]  
Les trois quarts des commandes proposées, je ne les connaissait pas. (shuf, cpio…)[/quote]  
shuf je ne le connaissais pas mais j’imaginais qu’il pouvait exister et son nom est intuitif.  
Note que C’est un bout de script pour zsh (j’ai pas fais gaffe). Ça utilise les globings étendues (dispo aussi en bash) pour trouver tout les fichiers d’une arbo) et le (.) c’est pour ne sortir que les fichiers.

[quote=“thuban”]Juste la fin, ça fait quoi exactement ça, si je puis me permettre ? :

```auto

```

[ul]  
[li]${musique##_/} : c’est l’équivalent d’un basename pour une variable[/li]  
[li][-f "${mount\_dir}/${musique##_/}"] : ça test l’existence de la musique sur le lecteur comme ça on ne le copie pas si c’est pas nécessaire.[/li][/ul]

Je suis allé un peu vite il faudrait faire ça :

`mount_dir='/media/mon_lecteur'
for musique in $(print -l mydir/**/*.{ogg,mp3,flac,wma}(.) | shuf) ; do
    [-f "${mount_dir}/${musique##*/}"] || cp -v "${musique}" "${mount_dir}"
    if ["$?" -ne 0]; then
        rm "${mount_dir}/${musique##*/}"
        exit
    fi
done`  
Si non tu va te retrouver avec des morceaux de musiques copiées.

---

<div class="post-metadata">

**Author:** ![thuban](https://www.debian-fr.org/user_avatar/www.debian-fr.org/thuban/32/4177_2.png) [@thuban](https://www.debian-fr.org/u/thuban)\
**Post date:** [Février 21, 2016, 12:49 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/290 "2016-02-21T12:49:31Z")

</div>

Je me disais bien que ça ne testait pas s’il restait assez de place.

Merci des précisions, c’est très instructif. Mais je trouve vraiment la syntaxe de zsh pas intuitive, je me sens plus à l’aise avec python, malgré quelques lignes de plus à écrire.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 12:49 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/291 "2016-02-21T12:49:32Z")

</div>

Pour le coup on parle de quelques dizaines.

Pou la syntaxe propre à zsh le globbing “\*\*” est assez classique et plutôt intuitif je trouve. Pour le (.), ça n’est pas intuitif mais ça se comprend ( (/) pour les dossiers, (\*) pour les exécutables, etc comme ls -F). Ce n’est pas une obligation de le mettre.

Ce serait pratique de faire un `shuf -e mydir/**/*.{ogg,mp3,flac,wma}(.)`mais la ligne de commande risquerait de devenir trop longue.

(Paf je viens de prendre un nouvelle claque de la par de zsh)  
Au lieu de ${musique##\*/} on peut écrire “${musique}”(:t) avec t comme tail.

Du coup ça donnerait :

`mount_dir='/media/mon_lecteur'
for musique in $(shuf -e mydir/**/*.{ogg,mp3,flac,wma}) ; do
    fichier="$musique"(:t)
    [[-f "${mount_dir}/$fichier"]] || cp -v "${musique}" "${mount_dir}"
    if ["$?" -ne 0]; then
        rm "${mount_dir}/$fichier"
        exit
    fi
done`

C’est assez clair je trouve. Et sa concision aide à sa compréhension. C’est une application directe d’un algo simple :

> [@](#):
>
> On construit la liste des chansons aléatoires. pour chacune d’elles ont la copie si elle n’est pas déjà dans le lecteur. Si on arrive pas à la copier, c’est que le lecteur est pleins, , on enlève la musique qui dépasse et on s’arrête.

Pour ton script, si tu veut une idée d’amélioration : pas de chance si la dernière chanson que l’on voulait copier faisait 70 Mio 🙂

---

<div class="post-metadata">

**Author:** ![thuban](https://www.debian-fr.org/user_avatar/www.debian-fr.org/thuban/32/4177_2.png) [@thuban](https://www.debian-fr.org/u/thuban)\
**Post date:** [Février 21, 2016, 12:49 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/292 "2016-02-21T12:49:33Z")

</div>

Alors oui justement, je n’ai pas réussi à me documenter suffisament sur statvfs, du coup je me suis inspiré d’exemples trouvé par ci par là. C’est pour ça que je proposais une correction, car je parie qu’il y a confusion entre les Byte et les bits ou quelque chose du genre?

Je garde ton script dans un coin pour le décortiquer convenablement et avancer! Merci 🙂

---

<div class="post-metadata">

**Author:** ![thuban](https://www.debian-fr.org/user_avatar/www.debian-fr.org/thuban/32/4177_2.png) [@thuban](https://www.debian-fr.org/u/thuban)\
**Post date:** [Février 21, 2016, 12:50 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/293 "2016-02-21T12:50:51Z")

</div>

Bon je n’ai pas réussi à trouver pour les 70Mo, je donne ma langue au chat!

> [@](#):
>
> Pour le coup on parle de quelques dizaines.

Tu exagères un tout petit peu, ce n’est pas autant. Il y a beaucoup de bling bling dans mon script (barre de progression…) et je l’ai écrit pour être facilement modifiable et compréhensible -variables en début de fichier, étapes supplémentaires… Donc pas plus de 10 c’est sûr 😉

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 12:50 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/294 "2016-02-21T12:50:54Z")

</div>

> [@](#):
>
> Bon je n’ai pas réussi à trouver pour les 70Mo, je donne ma langue au chat!

Imagine plus gros : Qu’est ce qui se passe si la dernière musique qu’il tente de copier fait 2Tios ? Imagine que c’est la première.

* * *

Réponse : si c’est la première tu n’aura pas de musique sur ton lecteur. C’est dommage de ne pas tenter la suivante, voir celle d’après… Ça ne coûte pas chère en terme de temps d’exécution (un stat pour chercher la taille des musiques) et la complexité de l’algo passe de 1,5N (donc O(N)) à 2N (donc O(N)).

---

<div class="post-metadata">

**Author:** ![thuban](https://www.debian-fr.org/user_avatar/www.debian-fr.org/thuban/32/4177_2.png) [@thuban](https://www.debian-fr.org/u/thuban)\
**Post date:** [Février 21, 2016, 12:50 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/295 "2016-02-21T12:50:57Z")

</div>

Ah, c’est vrai que je n’avais pas imaginé ce cas. Et puis ce n’est pas bien difficile à mettre en place (mettre un pass au lieu de break). Mais bon, comme au départ je vide le lecteur, ça me semblait peu probable.  
Cela dit, c’est dommage de ne pas TOUT remplir.

Merci 🙂

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 12:51 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/296 "2016-02-21T12:51:00Z")

</div>

> [@](#):
>
> Ah, c’est vrai que je n’avais pas imaginé ce cas.

L’expérience d’un développeur se voie à sa capacité à imaginer les cas les plus tordu.

---

<div class="post-metadata">

**Author:** ![thuban](https://www.debian-fr.org/user_avatar/www.debian-fr.org/thuban/32/4177_2.png) [@thuban](https://www.debian-fr.org/u/thuban)\
**Post date:** [Février 21, 2016, 12:51 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/297 "2016-02-21T12:51:06Z")

</div>

> [@](#):
>
> [quote=“thuban”]Ah, c’est vrai que je n’avais pas imaginé ce cas.

L’expérience d’un développeur se voie à sa capacité à imaginer les cas les plus tordu.[/quote]  
S’pèce d’expérimenté va! ![:016](https://www.debian-fr.org/uploads/default/original/1X/b259ae9d61776a18a151e35004995aa8715555b6.gif "langue-en-vert")

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 12:51 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/298 "2016-02-21T12:51:06Z")

</div>

> [@](#):
>
> [quote=“MisterFreez”][quote=“thuban”]Ah, c’est vrai que je n’avais pas imaginé ce cas.

L’expérience d’un développeur se voie à sa capacité à imaginer les cas les plus tordu.[/quote]  
S’pèce d’expérimenté va! ![:016](https://www.debian-fr.org/uploads/default/original/1X/b259ae9d61776a18a151e35004995aa8715555b6.gif "langue-en-vert") [/quote]  
Moi c’est les architectes qui m’impressionnent. Ils voient le cas particulier qui va planter ton code dans un cas qui arrivera 1 fois tout les jamais et qui broieras toutes tes protections, mais qu’il faut prendre en compte pour la fiabilité qu’on veut obtenir.

---

<div class="post-metadata">

**Author:** ![agentsteel](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/97f17d/32.png) [@agentsteel](https://www.debian-fr.org/u/agentsteel)\
**Post date:** [Février 21, 2016, 1:37 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/299 "2016-02-21T13:37:38Z")

</div>

Bonjour à tous,

Je soumets à votre expertise ce petit script CGI (nécessite un serveur http comme Apache) qui est un clone de Pastebin, version minimaliste (c’est mon truc ça 😛 )

N’hésitez pas à tester ça si vous avez 5 minutes, histoire de voir s’il n’y a pas de gros trous de sécurité par exemple.

```auto
#!/bin/sh
# -----------------------------------------------------------------------------
# Fredo's pastebin CGI script v01.11.2012
# -----------------------------------------------------------------------------
# http://agentoss.wordpress.com / fredo696@gmail.com
# -----------------------------------------------------------------------------
# Minimalist pastebin-like (no syntax coloring, no encryption, etc...)
# Pure shell! no perl! no python! no php! no database! (nearly no javascript!)
#
# The pastes are written in plain html files.
#
# Please report bugs!
#
# TODO: include "time to live" in paste filename
# TODO: simple antispam
# TODO: show recent pastes
# TODO: (security) log new pastes into a logfile (ip address, date, etc...)
# TODO: (security) send mail to admin at each new paste
#
#
# HOW TO USE :
#
# - Put this script in your cgi-bin directory
# (see your web server's configuration. For Debian systems with Apache
# it is /usr/lib/cgi-bin/ )
#
# - name it "paste"
# (if you want another name, reflect the changes in the "myurl" variable)
#
# - make this script executable (chmod +x).
#
# - Create a "pastebin" directory in your web server's document tree
# (eg. /var/www/pastebin ), make it writeable by the web server (chmod +w)
#
# - Create an .htaccess file in your "pastebin" directory, containing :
#
# Options -Indexes
# DefaultType text/html
#
# - Point your browser at : http://yourserver/cgi-bin/paste
#
# SECURITY :
#
# - Disable the listing of the pastebin directory
# "Options -Indexes" in your Apache configuration or .htaccess file
# (see http://httpd.apache.org/docs/2.2/howto/htaccess.html )
#
# - use your web server's auth capabilities to restrict access if needed
# (for Apache, see http://httpd.apache.org/docs/2.2/howto/auth.html )
#
# - setup SSL on your web server
# (for Apache, see http://httpd.apache.org/docs/2.2/ssl/ )
#
# IDEAS :
#
# - setup a cron job to automatically delete the pastes (crontab -e as root)
# eg. each day at 00:00 :
# 0 0 * * * find /srv/http/pastebin/ -name "paste.*" -delete
#
# or delete pastes which haven't been accessed in the last 7 days
# 0 0 * * * find /srv/http/pastebin/ -name "paste.*" -atime +7 -delete
#
#
# -----------------------------------------------------------------------------
#
# DISCLAIMER : USE AT YOUR OWN RISK!!!
#
# -----------------------------------------------------------------------------
# VARIABLES
# -----------------------------------------------------------------------------
# (relative) url of this cgi script
myurl="/cgi-bin/paste"

# name of the pastebin web directory (you could change it to something more
# "random", eg. "egrg4894afeo")
pastedirname="pastebin"

# full path to the web directory where the pastes will be written
# usually under /var/www/pastebin
pastedir="/var/www/$pastedirname"

# template name for the paste files (see : man mktemp)
# Append ".html" or, if you don't want a file extension,
# use the "DefaultType text/html" directive in your Apache config
# (or pastedir/.htaccess)
pastefilename="XXXXXXXX"

# sleep value in seconds (0 to disable) for extra delay between two pastes
# sort of "flood protection"
delay_between_pastes=0

# maximum allowed paste size in BYTES
# (this value is passed to the "maxlength" attribute of the <TEXTAREA>)
# set to "" for unlimited!
max_paste_length="65536"

# script debugging, set value to enable, unset to disable
DEBUG=
#
#
# -----------------------------------------------------------------------------
# main program
echo "Content-type: text/html"
echo ""
echo ""
# embedded css stylesheet
cat <<END
<!DOCTYPE HTML SYSTEM>
<HTML><HEAD><style type='text/css'>
body {
background-color: #e1ddd9; color: #564b47;
font-size: 12px; font-family: Verdana, Arial, Helvetica, Sans-Serif;
margin: 20px 180px 20px 180px; text-align: center;
}
#content {
width: 100%; padding: 8px; text-align: left;
background-color: #eeeeee; overflow: auto;
border-radius: 8px; border: 1px solid;
}
textarea { width: 100%; height: 50%; border-radius: 8px; }
.mybutton { border-radius: 8px; }
</STYLE><TITLE>Fredo's pastebin</TITLE></HEAD>
<BODY><H1>Fredo's pastebin</H1><DIV id="content">
END

# get first cgi parameter : the action to perform
mycommand=$QUERY_STRING

[$DEBUG] && echo "<br>(debug) mycommand=$mycommand"

case $mycommand in

# create new paste, then show link upon success
"createnew")

# TODO: check antispam

# read raw POST data (still encoded)
#read -n $CONTENT_LENGTH postdata
read postdata

[$DEBUG] && echo "<br>(debug) pastedata<pre>$postdata</pre>"

# TODO: check again is pastedata is empty
# useful to do when the page is refreshed

# we use the handy mktemp shell command to create a new file with a unique filename
mynewpastefile=$(mktemp --tmpdir="$pastedir" "$pastefilename")
if [! "$mynewpastefile"]; then
 echo "Unable to create new paste! Please report the problem to the system admin!"
else

# make the paste file readable by all
chmod +r $mynewpastefile

# get base filename and reconstruct full link URL
mynewpastebasename=$(basename "$mynewpastefile")
mynewpastelink="/$pastedirname/$mynewpastebasename"

# get some file stats ("last change" date)
mynewpastestats=$(stat -c "%z" $mynewpastefile)

# we add some nice CSS to the new paste
# IMPORTANT!
# the actual paste data is enclosed in a <TEXTAREA>
# so that html scripting and rendering is disabled!
cat >$mynewpastefile <<END
<!DOCTYPE HTML SYSTEM>
<HTML><HEAD><style type='text/css'>
body {
background-color: #e1ddd9; color: #564b47;
font-size: 12px; font-family: Verdana, Arial, Helvetica, Sans-Serif;
margin: 20px 180px 20px 180px; text-align: center;
}
#content {
width: 100%; padding: 8px; text-align: left;
background-color: #eeeeee; overflow: auto;
border-radius: 8px; border: 1px solid;
}
textarea { width: 100%; height: 50%; border-radius: 8px; }
.mybutton { border-radius: 8px; }
</STYLE><TITLE>Fredo's pastebin</TITLE></HEAD>
<BODY><H1>Fredo's pastebin</H1><DIV id="content">
<DIV style="text-align:right">
<SMALL><A HREF="$mynewpastelink">This paste</A> was created $mynewpastestats</SMALL>
</DIV><TEXTAREA rows="40" cols="80" readonly>
END

# we must "decode" the (form-encoded) data
# here we use the sed command for this!
# (see http://www.commandlinefu.com/commands/view/2285/urldecoding )
# furthermore, we need to replace the "HTML special chars" such as "<" and ">"
# to be sure no HTML content will be interpreted
# and we remove the "pastedata=" (see the form's textarea field name) extra text at the beginning
pasteddata=$(echo "$postdata" | sed -e's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g' \
 -e's/x3C/x26lt\;/g' -e's/x3E/x26gt\;/g' \
 -e's/+/ /g' -e's/pastedata\=//1' | xargs echo -e)

# write data to file
echo >>$mynewpastefile "$pasteddata"

# get pasted bytes count
mynewpastebytecount=${#pasteddata}

# add a nice footer
cat >>$mynewpastefile <<END
</TEXTAREA>
<DIV style="text-align:right"><SMALL>Size : $mynewpastebytecount bytes</SMALL></DIV><p>
<form name="return" action="$myurl?return">
<input type="submit" class="mybutton" value="create another paste">
</form>
</DIV>&copy;2012 <A HREF="http://agentoss.wordpress.com">AgentOSS</A></BODY></HTML>
END

# file created, show direct link
# To prevent form data from being resubmitted, we redirect to the newly created paste
# so basically the following message is not seen! (unless javascript is disabled)
cat <<END
Your paste is available <A HREF="$mynewpastelink" target="">here</A> (copy or save this link now!)
<p>
<form name="return" action="$myurl?return">
<input type="submit" class="mybutton" value="return">
</form>
<script>
location.href="$mynewpastelink"
</script>
END

fi

;;

*)

# show form for a new paste
# notice the "required" parameter for the textarea (html5)
# which saves us the need to manually check for an empty paste!
# NOTE : we limit the maximum size of the pasted data
# with the "maxlength" attribute of TEXTAREA (html5)
cat <<END
<form name="paste" method="POST" action="$myurl?createnew">
Paste your text
END

[$max_paste_length] && echo "<small> (maximum allowed size is $max_paste_length bytes)</small>"

cat <<END
<br>
<textarea name="pastedata" rows="40" cols="80" required maxlength="$max_paste_length"></textarea>
<p>
<input type="submit" class="mybutton" value="create">
</form>
END
;;

esac

# footer
cat <<END
</DIV>&copy;2012 <A HREF="http://agentoss.wordpress.com">AgentOSS</A></BODY></HTML>
END

# we could add a slight delay between pastes (flood protection)
sleep $delay_between_pastes

exit 0

```

edit: qques bugs corrigés, améliorations.

---

<div class="post-metadata">

**Author:** ![seb-ksl](https://www.debian-fr.org/user_avatar/www.debian-fr.org/seb-ksl/32/2946_2.png) [@seb-ksl](https://www.debian-fr.org/u/seb-ksl)\
**Post date:** [Février 21, 2016, 1:38 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/300 "2016-02-21T13:38:21Z")

</div>

Pour le plaisir du partage, même si je me doute que je n’ai rien inventé 🙂

Problématique initiale : pas de fonction de recherche de fichiers dans Thunar (le navigateur de fichiers d’XFCE)

Réponse : un petit script qui permet de rechercher fichier par nom ou par contenu

Utilisation : trouve {f|g} [MOTIF]

f: Trouver un fichier dont le nom contient [MOTIF] dans le répertoire courant (récursif)  
g: Trouver un fichier contenant [MOTIF] dans le répertoire courant (récursif)

[code]#! /bin/bash

case “$1” in  
’f’)

```
if [[$2 != ""]] ; then
	find ./ -iname "*$2*"
else
	read -p "Search: " query
	find ./ -iname "*$query*"
fi

```

;;

‘g’)

```
if [[$2 != ""]] ; then
	grep -r $2 ./*
else
	read -p "Search: " query
	grep -r $query ./*
fi

```

;;

\*)  
echo -e “\nUsage: $0 {f|g} [MOTIF]\n\nf: Find a file containing [MOTIF] in its name in current directory (recursive)\ng: Find occurences of [MOTIF] in files of current directory (recursive)\n”  
;;

esac[/code]

---

<div class="post-metadata">

**Author:** ![BBT1](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/ecc23a/32.png) [@BBT1](https://www.debian-fr.org/u/BBT1)\
**Post date:** [Février 21, 2016, 1:39 UTC](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820/301 "2016-02-21T13:39:13Z")

</div>

Quelques remarques sur la forme :

- toujours protéger l’expansion des variables qui pourraient contenir des espaces,
- si la commande est incorrecte, sortir avec un code de retour différent de 0

Sinon, le reste c’est juste une histoire de goût 😉

Version revue et corrigée :

[code]#!/bin/bash  
set -eu

function usage () {  
cat \>&2 \<\<EOF  
Usage: $0 {f|g} [MOTIF]

f: Find a file containing [MOTIF] in its name in current directory (recursive)  
g: Find occurences of [MOTIF] in files of current directory (recursive)  
EOF  
}

if [$# -ge 1]; then  
CMD="$1"  
else  
echo “Erreur: nombre d’argument insuffisant” \>&2  
usage  
exit 1  
fi

if [$# -ge 2]; then  
QUERY="$2"  
else  
read -p "Search: " QUERY  
fi

case “$CMD” in  
f)  
find . -iname “_$QUERY_”  
;;  
g)  
grep -r “$QUERY” \*  
;;  
\*)  
echo "Erreur: commande $CMD inconnue"  
usage  
exit 2  
;;  
esac[/code]

[Page précédente](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820.md?page=14)

[Page suivante](https://www.debian-fr.org/t/pour-les-scripts-cest-ici/3820.md?page=16)
