[zenity] Action "annuler" ne kill pas le processus

Autres projets et contributions
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

[zenity] Action "annuler" ne kill pas le processus

Message par cassyb »

salut,
J'ai récupéré des scripts qui à la base sont conçu pour nautilus-action mais qui peuvent s'utiliser avec thunar...

Le but de ce script c'est de créer une action "copier vers..." dans le menu contextuel du clic droit quand on selectionne un ou plusieurs fichiers (des personnes me l'ont demandé car ont du mal avec Ctrl+X et Ctrl+V)

Le problème c'est que si je copie une video dans /tmp et que j'annule ça me ferme bien la barre de progression mais pas la commande cp malgré le exit.

tel que c'est marqué dans le code, ça affichera "La copie a été annulée" une fois celle-ci terminée

J'ai essayé de récupérer $? (la réponse de zenity) dans la boucle while sans succès.

Merci pour votre aide.
Voici le code:

Code : Tout sélectionner

#! /bin/bash

# SRC
# https://help.ubuntu.com/community/Nautilus_Scripts
# http://ubuntuforums.org/showthread.php?t=101859
# http://ubuntuforums.org/showthread.php?t=417978
# http://forums.archlinux.fr/topic1223.html

# PRESENTATION: les +
# annulation fonctionnelle (kill process fils, residu supprimé)
# check de l'espace libre, des droits.

# EXECUTION
# à executer en mode graphique avec l'option %m dans nautilus-actions
# ou lancer en CLI en se plaçant dans un repertoire où se trouve un gros fichier puis executer Copievers.sh grosFichier.avi

# INITIALISATION 
copy="Copie en cours..."
title_copy="Veuillez patienter..."
title_success="Succès"
title_error="Erreur"
title_conflict="Conflit durant la copie"
title_select="Selectionnez un répertoire"
error="Une erreur est survenue lors de la copie"
error_w="Vous n'avez pas les droits en écriture sur"
error_s="Pas assez espace disque!"
success="correctement copié(s)"
progress="Copie en cours"
conflict="Voulez-vous remplacer"
cmd="cp -Rp"
copied=0
nbFiles=0

# FONCTIONS
function copie ()
{
	ORIG_SIZE=`du -k "$arg"|awk '{print $1}'`
	checkFreeSpace $ORIG_SIZE
	$cmd "$arg" "$location" &
	CP_SIZE=`du -k "$location/$arg"|awk '{print $1}'`
	(
	while [ $CP_SIZE -ne $ORIG_SIZE ]; do
		# un echo est obligatoire dans ce while
		echo $(( $(( $CP_SIZE * 100 )) / $ORIG_SIZE ))
		CP_SIZE=`du -k "$location/$arg"|awk '{print $1}'`
	done
	echo 100
	) | zenity --progress --auto-close --text "$copy \"$arg\"..."
	# ^ barre de progression de zenity
	# v on controle si annulation ou pas.	
	controlCp
}

# un paramètre: la taille du fichier 
function checkFreeSpace ()
{
# location sera de la forme /, /tmp, /home, /opt...
# on split le path pour trouver la partition
	part=`echo $location | cut -d'/' -f2`
	findit=`df | grep $part`
	# si findit est vide alors concerne la partition /
	if [ "$findit" == "" ]; then
		findit=`df / | grep /`
	fi
		tab=( $findit )
		# point de montage se trouve sur 5
	    	mountPoint=${tab[5]}
		# l'espace libre sur 3
	    	freeSpace=${tab[3]}
	if [ $1 -gt $freeSpace ]
	then
		zenity --error --text="$error_s" --title "$title_error";
		exit 1
	fi
}

function controlCp ()
{
	# On peut utiliser $? ou ${PIPESTATUS[0]}
	if [ "$?" != "0" ]; then
		# si annulation on kill le fils et on sort du script
		killChildProcess
		# on vire le residu
		pathfile="$location/$arg"
		# on evite les rm -R avec pour paramètre * ~ / . 
		if [ ${#pathfile} -gt 1 ] && [ ${#location} -gt 1 ] && [ ${#arg} -gt 1 ]; then
			rm -R "$pathfile"
		fi		
		exit 1
	else copied=`expr $copied + 1`
	fi
}

function killChildProcess ()
{
	# normalement il n'y en a qu'un seul...au cas où.
	for child in $(ps --ppid $$ -o pid,cmd | grep -R "$cmd" | awk '{print $1}')
	do
	  kill $child
	done
}

# TRAITEMENT
# on renseigne le repertoire de destination
location=`zenity --file-selection --directory --title="$title_select"`
if [ "$?" = 0 ]; then
# si on a pas annuler...on check les droits en écriture
	if [ -w "$location/$arg" ]; then
		for arg
		do
			nbFiles=`expr $nbFiles + 1`
			# on vérifie si le fichier courant n'existe pas à la destination
			if [ -e "$location/$arg" ]; then
			# s'il existe message -> conflit
			zenity --question --title="$title_conflict" --text="$conflict $location/$arg ?"
				if [ "$?" = 0 ]; then
				# si on souhaite tout de même écraser
					copie
				fi
			else 
			# s'il n'existe pas on copie
				copie
			fi
		done
		# on check copied / nbFiles
		if [ $copied -gt 0 ]; then
			zenity --info --text="$copied/$nbFiles $success" --title "$title_success";
		fi

	else zenity --question --title="$title_error" --text="$error_w $location"
	fi
fi
Dernière modification par cassyb le dim. 13 janv. 2008, 18:25, modifié 6 fois.
Avatar de l’utilisateur
tuxce
Maître du Kyudo
Messages : 6677
Inscription : mer. 12 sept. 2007, 16:03

Message par tuxce »

le souci, c'est que cp écrit sur le disque au fur et à mesure, même si tu l'annules, une partie de la copie sera effectué.

pour l'annuler, il faudrait le killer, par contre, je sais pas s'il y a un moyen d'avoir le pid du processus qui vient d'etre lancé, sinon, tu peux l'obtenir avec une commande du genre:

Code : Tout sélectionner

ps --ppid $$ | grep ' cp$'
pour etre sur de ne pas prendre le pid d'une autre commande de copie

remarque s'il y a un moyen plus élégant, je suis intéréssé :)
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

merci tuxce mais mon pb n'est pas dans l'immédiat de savoir comment killer un processus fils d'un script père (je verrais + tard)
mon pb c'est que je n'arrive même pas à récupérer l'evenement annuler $?=1 dans le while (pour après killer le cp, faire un rm du fichier temporaire,envoyer une alerte)
C'est + un pb d'algo en bash (portée de variable + exactement) que de commande unix en fait.
Dans mon while si je fais

Code : Tout sélectionner

   if [ "$?" = 1 ]; then
      zenity --info --text="La copie a été annulée" --title "Annulation";
      exit 1
   fi 
ça ne fais rien...
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

J'ai trouvé 2 pistes et d'après les 1ers essais ça marche...
http://forum.ubuntu-fr.org/viewtopic.ph ... 5#p1042795
mais j'ai l'impression que ça fait bricolage...
et
http://www.askdavetaylor.com/how_do_i_f ... _unix.html

Je remplacerais mon script dans le post 1 une fois corrigé.
Avatar de l’utilisateur
tuxce
Maître du Kyudo
Messages : 6677
Inscription : mer. 12 sept. 2007, 16:03

Message par tuxce »

pour le 2eme lien, la commande avec --ppid est quand même plus simple

pour en revenir à ton problème, on dirait que le while n'est pas arrété par la fermeture de zenity...
tu peux le vérifier en insérant dans le while:

Code : Tout sélectionner

echo qq chose >/dev/stderr
enfin si tu le lances depuis une console.

j'ai essayé en modifiant le code de cette facon:

Code : Tout sélectionner

   while true; do
      echo $(( $(stat -c %s "$location/$arg") * 100 / $ORIG_SIZE ))
   done
ca a l'air d'être mieux, par contre, je vois pas trop pourquoi ca n'arrete pas le while avec l'autre code.
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

ouais j'avais remarqué que ça marchait que s'il y a un echo (de n'importe quoi) dans le while...
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

j'ai une question...
j'aimerais mettre ma commande dans une variable genre
cmd="cp -Rp"
pour pouvoir l'utiliser dans une autre fonction.

function copie () {
`$cmd "$arg" "$location" &`
...
}

le soucis c'est que c'est pas interpreté comme:
cp -Rp "$arg" "$location" &
mais comme:
cp -Rp "$arg" "$location"

comment faire en sorte que le & soit reconnu?
Avatar de l’utilisateur
tuxce
Maître du Kyudo
Messages : 6677
Inscription : mer. 12 sept. 2007, 16:03

Message par tuxce »

tu enleves les ` :P
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

avec les fêtes, la rentrée je n'avais plus retouché le script.
Je viens de le mettre à jour avec controle de l'espace disque + controle du paramètre rm-R pour éviter les mauvaises blagues si lancé en console.

J'ai le message:
line 80: 14019 Complété $cmd "$arg" "$location"

mais je suppose que c'est un message normal.
si à l.39 je mets cp -Rp à la place de $cmd, je n'ai plus le message.

Je le modifierais plus tard pour améliorer le messsage "1/1 fichier(s) copié(s)".
Répondre