# Exécution de la commande "diff" dans un script ksh



## hacaira (10 Juin 2008)

Bonsoir à tous,

Cela fait maintenant quelques semaines que je me gratte la tête et que j'essaie de terminer un script me permettant de faire une synchronisation de répertoires en utilisant la commande diff et la commande cp.

Tout ce passe bien lorsque je crée les variables et que je lance les commandes via le prompt mais le script lui, se plante systématique lors de l'exécution de la commande diff (le fichier vers lequel les infos sont redirigées est vide).

Pour le tester il suffit de créer deux répertoires ayant les mêmes fichiers et de rajouter un fichier au répertoire source.    

#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

seekr=$(id root | grep uid=0 | awk '{print $1}' | awk -F "root" '{print $1}' ) export seekr
cd $HOME

osascript -e 'tell application "Finder" to activate'

if [ "$seekr" = "uid=0(" ]; then
osascript -e 'tell application "Finder" to display dialog "Bienvenue dans le service de synchronisation des répertoires. Veuillez stopper tous les autres programmes avant de continuer." with title "ThroughDiff - Utilisateur root activé" buttons {"continuer..."} default button 1 with icon 1'

else
osascript -e 'tell application "Finder" to display dialog "Bienvenue dans le service de synchronisation des répertoires. Veuillez stopper tous les autres programmes avant de continuer." with title "ThroughDiff - Utilisateur root désactivé" buttons {"continuer..."} default button 1 with icon 1'
exit 0
fi

osascript -e 'tell application "System Events" to keystroke "h" using {command down, option down}'

RepA=$(osascript -e 'tell application "Finder" to choose folder with prompt "CHOIX DU REPERTOIRE SOURCE"') export RepA
if [ "$RepA" = "" ]; then
exit 0
fi

RepB=$(osascript -e 'tell application "Finder" to choose folder with prompt "CHOIX DU REPERTOIRE CIBLE"') export RepB
if [ "$RepB" = "" ]; then
exit 0
fi

Source=$(osascript -e "POSIX path of \"$RepA\"") export Source
Cible=$(osascript -e "POSIX path of \"$RepB\"") export Cible

diff -riEb -x ".*" $Source $Cible | grep -a $Source | grep -v "differ" >./HDUpdateLog.txt

catresult=$(cat -b ./HDUpdateLog.txt | awk -F "/: " '{print $2}') export catresult
nombfich=$(wc -l ./HDUpdateLog.txt | awk '{ print $1 }') export nombfich


if [ "$nombfich" ="0" ]; then
/usr/bin/osascript <<EOT
        tell application "Finder"
                display dialog "Tous les fichiers du répertoire \"$Source\" sont present dans \"$Cible\""buttons {"Ok"} default button 1 with icon 1
        end tell
EOT
rm ./HDUpdateLog.txt
exit 0

else
/usr/bin/osascript <<EOT
        tell application "Finder"
display dialog "Il y a \"$nombfich\" fichiers à copier. Liste des nouveaux fichiers du répertoire \"$Source\" \"$catresult\" Voulez-vous les copier dans le répertoire de destination?" buttons {"Stopper", "Copier"} default button 2 cancel button 1
        end tell
EOT
cp -nrpv $Source $Cible >./HDUpdateCPLog.txt
cat ./ThroughDiffCplog | grep -v 'not o*' >./HDUpdateCPShortLog.txt
osascript -e 'tell application "Finder" to display dialog "Tous les fichiers ont été copiés avec succès" buttons {"Ok"}'
rm ./HDUpdateLog.txt
exit 0
fi


La commande diff est sensée comparer le contenu de deux répertoires (ainsi que leurs sous répertoires), j'utilise grep pour n'avoir que les fichiers appartenants au répertoire source et pour éviter les messsages concernant une différence de bits (grep -v "differ") redirigée vers HDupdateLog.txt

J'utilise l'éditeur vi et je lance le script via la commande ./HDupdate.sh

Tout de passe bien jusqu'à ce que la commande diff entre en action???

Pourriez-vous me venir en aide, je sèche.


----------



## grumff (11 Juin 2008)

Un diff ça compare le contenu de deux fichiers, pas de répertoires... Je comprends pas bien comment tu pourrais faire ça sans passer par un ls ou un find.

Ton diff isolé du reste du script, ça donne quoi ?


----------



## boissonnfive (11 Juin 2008)

Coucou,

es-tu obligé d'utiliser diff pour ce travail?

Si tu veux bien utiliser un autre outil, je te conseille: RSYNC.
Il a été créé pour ça: synchroniser des répertoires (locaux ou distants) et je crois qu'il est présent de base sur mac os x (??)
Tu peux le lancer une première fois pour qu'il liste les fichiers différents (option -n):
rsync -navu [--delete] source dest
Tu valides.
Tu le lances une deuxième fois pour qu'il fasse la synchronisation.
rsync -avu [--delete] source dest
(l'option delete va permettre une synchronisation mirroir: à la fin le dossier dest est
identique au dossier source) 
Sinon, désolé, je n'ai pas le temps de regarder ton script...


----------



## boissonnfive (11 Juin 2008)

Re-coucou!

Finalement j'ai trouvé le temps de lire ton script.
Et chez moi il marche bien, à part que:
 - les fichiers différents ne sont pas écrasés dans le dossier destination par ceux du dossier source
(dû à l'option -n de cp)
 - quand un des dossiers a un nom avec des espaces, la commande diff plante (il faut mettre les noms de répertoires entre "" dans le script ligne 33:
diff -riEb -x ".*" "$Source" "$Cible" | grep -a $Source | grep -v "differ" >./HDUpdateLog.txt
)

Est-ce que ça t'a aidé?
En tout cas, bravo pour ce script bien sympa.


----------



## hacaira (11 Juin 2008)

Bonjour à tous,

Merci pour tous les messages et les encouragements, ça fait plaisir.

La commande diff ne pose pas de problème pour comparer le contenu de répertoires (elle est aussi faites pour cela).

Je connais Rsync mais j'aimerai utiliser diff et cp (histoire de maîtriser ces commandes).

Oui la commande fonctionne bien à partir du prompt.

*Boissonnfive
*
Merci pour les infos concernant la mise entre guillemets des strings.
J'ai fait les modifs (pour tout les endroits ou se trouve ces strings) et .... ça marche, merci.

Enfin, j'ai toujours un petit soucis avec applescript. Le dernier 'dialog' du script contient 2 boutons (un stopper et un copier). Lorsque je clique sur stopper, il effectue quand même la copie au lieu de sortir de l'appli.

Voici le code : 


/usr/bin/osascript <<EOT
tell application "Finder"
display dialog "Il y a \"$nombfich\" fichiers à copier. Liste des nouveaux fichiers du répertoire \"$Source\" \"$catresult\" Voulez-vous les copier dans le répertoire de destination?" buttons {"Stopper", "Copier"} default button 2 cancel button 1
end tell
EOT


J'ai l'impression que l'option 'cancel button 1' ne fonctionne pas. Une idée?
Merci
Fred


----------



## fvilers (12 Juin 2008)

Sous Unix, un répertoire n'est qu'un fichier, donc tu peux facilement comparer le contenu de deux répertoires. D'ailleurs, sous Unix, tout est fichier


----------



## hacaira (12 Juin 2008)

J'ai trouvé une nouvelle erreur 
./HDUpdate.sh: line 39: [: 0: unary operator expected

Concernant la ligne 39
if [ "$nombfich" ="0" ]; then

Je ne vois pas d'erreur, et vous?


----------



## hacaira (12 Juin 2008)

J'ai trouvé,
j'ai remplacé la ligne par 

if [ "$nombfich" -eq 0 ]; then

Il me reste toujours ce problème de cancel button... J'y retourne

Le script, mis à jour, est en attachement.


----------



## tatouille (14 Juin 2008)

hacaira a dit:


> Bonjour à tous,
> 
> Merci pour tous les messages et les encouragements, ça fait plaisir.
> 
> ...



sha1 et creer une db sqllite, c'est assez crapy aucun lock ... et prefere de loin ditto


----------



## hacaira (14 Juin 2008)

Ben si j'avais voulu du travail de pro, je l'aurais écrit en C mais là je le fais simplement pour maîtriser la syntaxe des osascripts.

Personne d'autre?

J'ai encore essayé autre chose pour la fin :

result=$(osascript -e 'tell application "Finder" to display dialog "Il y a \"$nombfich\" fichiers à copier. Liste des nouveaux fichiers du répertoire \"$Source\" \"$catresult\"
 Voulez-vous les copier dans le répertoire de destination?" buttons {"Stopper", "Copier"} default button "Copier"')

if [[ "$result" = "button returned:Stopper" ]]; then
rm ./HDUpdateLog.txt
exit 0
fi
if [[ "$result" = "button returned:Copier" ]]; then
cp -nrpv "$Source" "$Cible" >./HDUpdateCPLog.txt
cat ./HDUpdateCPLog.txt | grep -v 'not o*' >./HDUpdateCPShortLog.txt
osascript -e 'tell application "Finder" to display dialog "Tous les fichiers ont été copiés avec succès" buttons {"Ok"} default button "Ok"'
rm ./HDUpdateLog.txt
exit 0
fi

Ca marche, sauf que c'est pas le contenu des variables (\"$nombfich\" "$Source\"et \"$catresult\") qui est affiché mais le nom de la variable.
Un problème de syntaxe je crois.
Quelqu'un pourrait me conseiller un site concernant des infos sur la syntaxe de l'osascript?
Merci


----------



## hacaira (14 Juin 2008)

Ca y est, tout fonctionne.

J'ai résolu le problème qui était bien lié à la syntaxe

result=$(/usr/bin/osascript <<EOT
...
EOT)


Trouvé sur MacBidouille.

Malgré tout j'aimerai bien savoir si il existe un site complet sur osascript?
Merci


----------



## tatouille (15 Juin 2008)

hacaira a dit:


> Ben si j'avais voulu du travail de pro, je l'aurais écrit en C mais là je le fais simplement pour maîtriser la syntaxe des osascripts.




quelqu'un m'explique le rapport? , parce que tu utilises osascript tu fais un truc de porco?

man lockfile 
la notion de lock aquire et de lock release  

n'a pas grand chose avoir, tout a fait fesable avec osascript et bash, whatever, merci pour ceux qui font des choses pro-pre avec...

ca n'a rien avoir avec l'idee de profesionnel 

je connais beaucoup de gens qui programment par interet/passion/hobby (et ce n'est pas leur metier) et qui sont propres et coherents


----------



## hacaira (18 Juin 2008)

Va t'en chicaner ailleurs... Dépressif


----------



## tatouille (18 Juin 2008)

hacaira a dit:


> Va t'en chicaner ailleurs... Dépressif



 :love:, c'est puissant comme vane mrd, newb, t'as autre chose ?, remarque c'est a la hauteur de ton code
merdique :rateau:


----------



## hacaira (18 Juin 2008)

Toi qui te prétends expert et qui n'a sûrement rien de bon entre les deux oreilles, tu devrais savoir que ce site n'est pas un endroit ou l'on se laisse aller à la vulgarité. Un peu de tenue, que diable. 
Tu n'as d'un expert que la prétention, il te manque la modestie et la pédagogie.

Et si t'es pas capable de tenue ou de modestie, essayes au moins de soigner ta grammaire en commençant par l'axiome 'sujet-verbe-complément'. 

A+
Bisous


----------



## tatouille (18 Juin 2008)

ok donne moi ton chemin Hamiltonien

t'as commande est dangeureuse:

1- tu ne peux pas savoir si une resource est busy ou non
2- tu ne controles pas les periodes d'ecritures dessus, il est impossible de savoir si tu peux copier
les resources sans l'obtention d'un lock qui averti tout autre proc qu'un travail est en cours
3- ditto copie les resources fork et assure l'integrite des datas

rsync est fait pour ca

de plus il existe les balises "code" afin de permettre une meilleur lecture, 
de plus ton code est un melange de franc-anglais avec des labels qui devrait etre localizes
et qui sont hardcodes

de plus lacune syntaxique concernant ton shell


```
osascript <<EOF
ignoring application responses 
    tell application "loginwindow" to «event aevtrrst»
end ignoring
EOF
```


```
seekr=$(id root | grep uid=0 | awk '{print $1}' | awk -F "root" '{print $1}' ) export seekr
cd $HOME

osascript -e 'tell application "Finder" to activate'

if [ "$seekr" = "uid=0(" ]; then
osascript -e 'tell application "Finder" to display dialog "Bienvenue dans le service de synchronisation des répertoires. Veuillez stopper tous les autres programmes avant de continuer." with title "ThroughDiff - Utilisateur root activé" buttons {"continuer..."} default button 1 with icon 1'
```
c'est toujour vrai, je ne sais pas ce que tu essayes de determiner (mon utilisateur root est desactive)
$UID peut etre?


```
declare -r MSG="hello world!"

osascript <<EOF
do shell script "echo $MSG" with administrator privileges
EOF
```
et j'en passe... guigui, car beaucoup de points ne sont pas visites 

et fallait le dire avant que je t'avais vexe newb


----------

