Marrant
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.
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’
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]
# 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]
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 :
detox -r Musique/
Le script (modifié après discussion ci-dessous. Voir aussi la solution proposée par Misterfreez en zsh):
#!/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
Excuse-moi mais :
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=“MisterFreez”]Excuse-moi mais :
[/quote]
Surtout pas! Tiens, on dirait que je vais apprendre des trucs!
[quote=“MisterFreez”]
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 ? :
[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 ? :
[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.
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.
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 :
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
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
Bon je n’ai pas réussi à trouver pour les 70Mo, je donne ma langue au chat!
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
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)).
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
L’expérience d’un développeur se voie à sa capacité à imaginer les cas les plus tordu.
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!
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! [/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.
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.
#!/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>©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>©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.
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]
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]