diff --git a/ufile b/ufile index 9b3cef1..2f67f1b 100755 --- a/ufile +++ b/ufile @@ -21,16 +21,19 @@ forme pattern:destdir[:renamef] La fonction doit définir la variable dest qui est le nouveau nom. Si la fonction retourne un code d'erreur autre que zéro, la règle est ignorée. Si le nouveau nom contient un chemin, destdir est ignoré et le fichier est - déplacé dans le répertoire spécifié. + déplacé dans le répertoire spécifié avec le nom spécifié. Si dest est un + tableau avec plusieurs destinations, alors le fichier est copié en plusieurs + fois. Si dest est de la forme [user@]host:path alors le fichier est copié par scp sur l'hôte spécifié vers la destination spécifiée, sauf si l'hôte courant est déjà celui mentionné dans la valeur, auquel cas la copie est faite directement dans le répertoire spécifié. Si le user et l'hôte courant sont déjà à la valeur spécifiée, alors la copie - est faite en local sans utiliser scp. Cependant, path est alors le chemin - complet vers le fichier destination. Si on veut copier le fichier sans le - renommer vers un répertoire, il faut mettre un slash e.g user@host:destdir/ - variables non documentées: interaction(=-i) + est faite en local sans utiliser scp sauf si l'option --force-scp est utilisée + Le chemin spécifié, en local ou distant, est toujours le chemin complet vers + le fichier destination. Si on veut copier le fichier sans le renommer vers un + répertoire, il faut mettre un slash e.g destdir/ ou user@host:destdir/ + variables pouvant être définies mais non documentées: interaction(=-i) USAGE $scriptname [options] @@ -39,6 +42,15 @@ OPTIONS -c, --config CONFIG Utiliser le fichier de configuration spécifié au lieu de la valeur par défaut ~/etc/default/ufile + --file + Classer les fichiers spécifiés. C'est l'action par défaut + -S, --ssh SSH + S'il faut classer sur un hôte distant avec scp, utiliser le programme + spécifié pour la connexion par ssh + --force-scp + Toujours utiliser scp pour une copie distante. Par défaut s'il est + déterminé que l'hôte distant est en réalité l'hôte courant, alors la + copie est effectuée directement. -n, --fake Afficher les opérations qui seraient faites -l, --list @@ -55,14 +67,52 @@ function joinp() { echo "$pf" } +function __check_destdir() { + local destdir="$1" rule="$2" + if [ -z "$destdir" ]; then + eerror "$rule: règle invalide: destdir est vide" + return 1 + fi + return 0 +} +function __set_dest() { + local dest="$1" destdir="$2" filename="$3" force_scp="$4" + local userhost remotedir destname + if [[ "$dest" == *:* ]]; then + splitpair "$dest" userhost remotedir + if [ -z "$force_scp" ] && check_userhostname "$userhost"; then + # on est déjà avec le bon user sur le bon hôte + if [ -n "$remotedir" ]; then + splitpath "$remotedir" destdir destname + setx destdir=abspath "$destdir" "$HOME" + [ -n "$destname" ] || destname="$filename" + setx dest=joinp "$destdir" "$destname" + else + setx dest=joinp "$HOME" "$filename" + fi + fi + elif [[ "$dest" == */* ]]; then + splitpath "$dest" destdir destname + [ -n "$destname" ] || destname="$filename" + setx dest=joinp "$destdir" "$destname" + setx dest=abspath "$dest" + else + __check_destdir "$destdir" "$rule" || return 1 + setx dest=joinp "$destdir" "$filename" + fi + upvar dest "$dest" + return 0 +} + args=(% --help '$exit_with display_help' -c:,--config: config= + --file action=file -S:,--ssh: SSH= + --force-scp force_scp=1 -n,--fake fake=1 -l,--list action=list -e,--edit action=edit - --file action=file ) parse_args "$@"; set -- "${args[@]}" @@ -139,6 +189,7 @@ for rule in "${RULES[@]}"; do done # faire le classement effectif +r= for file in "$@"; do [ -f "$file" -o -n "$fake" ] || { eerror "$file: fichier introuvable. il sera ignoré" @@ -150,66 +201,76 @@ for file in "$@"; do found= for rule in "${RULES[@]}"; do splitpair "$rule" pattern r2 - splitpair "$r2" destdir r3 + splitpair "$r2" odestdir r3 splitpair "$r3" renamef r4 - if [ "${destdir#"~/"}" != "$destdir" ]; then - destdir="$HOME/${destdir#"~/"}" + if [ "${odestdir#"~/"}" != "$odestdir" ]; then + odestdir="$HOME/${odestdir#"~/"}" + elif [ "$odestdir" == "~" ]; then + odestdir="$HOME" fi eval "[[ \"\$filename\" == $(qwc "$pattern") ]]" || continue - userhost= - destname="$filename" + unset dest interaction=--DEFAULT-- if [ -n "$renamef" ]; then - dest= - "$renamef" "$filename" "$pf" "$destdir" || continue - if [ -n "$dest" ]; then - if [[ "$dest" == *:* ]]; then - splitpair "$dest" userhost remotedir - if check_userhostname "$userhost"; then - # on est déjà avec le bon user sur le bon hôte - userhost= - if [ -n "$remotedir" ]; then - [ "$interaction" == --DEFAULT-- ] && interaction= - splitpath "$remotedir" destdir destname - [ -n "$destname" ] || destname="$filename" - fi - fi - elif [[ "$dest" == */* ]]; then - setx dest=abspath "$dest" - setx destdir=dirname -- "$dest" - setx destname=dirname -- "$dest" - else - destname="$dest" - fi - fi + "$renamef" "$filename" "$pf" "$odestdir" || continue fi - [ "$interaction" == --DEFAULT-- ] && interaction=-i - - if [ -z "$userhost" -a -z "$destdir" ]; then - eerror "$rule: règle invalide: destdir est vide" - break - fi - - if [ -n "$userhost" ]; then - estep "$filename --> $dest" - ask_yesno $interaction "Voulez-vous continuer?" O || { found=x; break; } - - docmd scp ${SSH:+-S "$SSH"} "$file" "$dest" || die "problème lors de la copie du fichier" - + if is_array dest; then + array_copy tmpdests dest + dests=() + for dest in "${tmpdests[@]}"; do + __set_dest "$dest" "$odestdir" "$filename" "$force_scp" || break + array_add dests "$dest" + done + elif is_defined dest; then + __set_dest "$dest" "$odestdir" "$filename" "$force_scp" || break + dests=("$dest") else - setx dest=joinp "$destdir" "$destname" - estep "$filename --> $dest" - ask_yesno $interaction "Voulez-vous continuer?" O || { found=x; break; } - - docmd mkdir -p "$destdir" || die "$destdir: impossible de créer le répertoire" - docmd mv -i "$file" "$dest" || die "problème lors du déplacement du fichier" + __check_destdir "$odestdir" "$rule" || break + setx dest=joinp "$odestdir" "$filename" + dests=("$dest") fi - found=1 + + i=1 + mvi=${#dests[*]} + for dest in "${dests[@]}"; do + if [[ "$dest" == *:* ]]; then + [ "$interaction" == --DEFAULT-- ] && int= || int="$interaction" + estep "$filename --> $dest" + ask_yesno $int "Voulez-vous continuer?" O || { + r=1; found=x; break + } + docmd scp ${SSH:+-S "$SSH"} "$file" "$dest" || die "problème lors de la copie du fichier" + + else + [ "$interaction" == --DEFAULT-- ] && int=-i || int="$interaction" + estep "$filename --> $dest" + ask_yesno $int "Voulez-vous continuer?" O || { + r=1; found=x; break + } + setx destdir=dirname -- "$dest" + docmd mkdir -p "$destdir" || die "$destdir: impossible de créer le répertoire" + if [ $i -eq $mvi ]; then + mvdesc="du déplacement" + mvcmd=mv + else + mvdesc="de la copie" + mvcmd=cp + fi + docmd "$mvcmd" -i "$file" "$dest" || die "problème lors $mvdesc du fichier" + fi + i=$(($i + 1)) + done + + [ -n "$found" ] || found=1 break done + if [ -z "$found" ]; then ewarn "$file: aucune correspondance n'a été trouvée" fi done + +[ -n "$r" ] || r=0 +exit $r