# [script] shift ... mais sur une variable ...

## loopx

Bonjour, 

Je fais un script de déploiement via SSH. Tout va bien pour le moment, sauf que j'ai un petit problème pour effectuer un truc : 

Il y a "shift" qui permet de décaller tout les paramètres de 1 vers la gauche (car j'ai 1x nom de répertoire et Nx nom de fichier ... je peux récupérer toutes la liste des fichiers en 1 paramètre). Or, après modification de mon script (trop basique au début), les paramètres ne se trouve plus ... dans @$ ... je me retrouve avec une variable qui contient des variables ... cette variable doit être "shiftée" de 1 vers la gauche. Possible en bash ?

Et on peut creuser un rien plus ... Dans mon/tout script, il y a des paramètres. Comment font, les gens qui écrivent des scripts, pour récupérer leurs paramètres ? Car il peuvent être dans un ordre différents etc etc ... 

Voici les paramètres de mon bête script .. :

<répertoire> <fichier1> [fichier2] [fichier3] [...]

Dans ces paramètres, j'ai ajouté un "--do-it" qui permet de "faire l'action" (c'est une sécurité ; ce script ne sera utilisé QUE par un humain). Problème : si je le met à gauche, le shift original foire (dans la liste des fichiers, j'aurais le répertoire ....) et si je place pas ce "--do-it", le script ne fait qu'un résumé....

Alors, suis un peu bloqué dans ma logique la   :Rolling Eyes: 

----------

## netfab

 *loopx wrote:*   

> Comment font, les gens qui écrivent des scripts, pour récupérer leurs paramètres ? Car il peuvent être dans un ordre différents etc etc ... 
> 
> 

 

Il ne faut pas faire le traitement des paramètres en même temps que le parsing.

```

$ cat parametres.sh 

#!/bin/bash

param_1='no'

param_2='no'

while [ $# -ne 0 ];

do

   case $1 in

      '--param_1')   param_1='yes' ;;

      '--param_2')   param_2='yes' ;;

      *) echo 'unknown :(' && exit 1 ;;

   esac

   shift

done

[ ${param_1} = 'yes' ] && echo 'parametre 1 :-)'

[ ${param_2} = 'yes' ] && echo 'parametre 2 :-)'

$ bash parametres.sh --param_1 --param_2

parametre 1 :-)

parametre 2 :-)

$ bash parametres.sh --param_2 --param_1

parametre 1 :-)

parametre 2 :-)

```

Pour la première question, il y a sûrement moyen de faire plus simple en traitant le problème différemment.Last edited by netfab on Thu Oct 08, 2009 4:20 pm; edited 1 time in total

----------

## ghoti

Sinon, il y a moyen de "splitter" une chaîne au moyen de #,##,% et %%

```
#! /bin/sh

###

# "split_string"

###

t="/rep/fichier1 /rep/fichier2 /rep/fichier3"

echo "string="$t

echo

 

echo "Premier élément= "${t%% *}

echo "Reste de la chaîne= "${t#* }
```

```
# ./split_string

string=/rep/fichier1 /rep/fichier2 /rep/fichier3

Premier élément= /rep/fichier1

Reste de la chaîne= /rep/fichier2 /rep/fichier3
```

----------

## rg421

Il y a aussi moyen de repositionner les paramètres positionnels: ça t'évitera peut-être une réécriture

```
$ echo "$@"

$ mavar="param1 param3 param3"

$ set -- $mavar

$ echo "$@"

param1 param3 param3
```

Après tu shifts...

----------

## loopx

 *netfab wrote:*   

>  *loopx wrote:*   Comment font, les gens qui écrivent des scripts, pour récupérer leurs paramètres ? Car il peuvent être dans un ordre différents etc etc ... 
> 
>  
> 
> Il ne faut pas faire le traitement des paramètres en même temps que le parsing.
> ...

 

L'idée est pas mal, mais le problème, c'est que j'ai des "data" dans les paramètres aussi ...    et surtout le fait que ces "data" (des noms de fichier) sont au nombre de N (soit, de 1 à n ...) ...

----------

## loopx

Bon, hum, suis un peu perdu ... je vais vous balancer le script  :Very Happy: 

```
[laurent@workstation script]$ cat ssh_remote_file_copy

#!/bin/bash

# Last update by moi :) on 20091009 :

#       - made this script generic ; make it crate directory if not existing

# Use :

#       ssh_remote_file_copy [--do-it] <directory> <file1> [file2] [...]

##############################################################################

SERVERS_ALL="serveur1 serveur2"

#should be set to 0 for security purpose

CREATE_FOLDER=0

USERNAME="<username>"

#FUNCTION-------------------------------------------------------------------------------------------

#print summary of the wanted action

summary() {

        echo "> Summary :"

        echo "> --------"

        echo ">>> Servers where to deploy files = '$SERVERS_ALL'"

        echo ">>> Directory in those servers = '$DIRECTORY'"

        echo ">>> Files to deploy = '$FILES'"

        check_file

        check_directory

        echo

        echo "> All seem to be fine ; just add '--do-it' switch to run this action"

}

#check for file presence before anything

check_file() {

        error=0

        echo "> Checking for file presence ..."

        for file in $FILES; do

                if [ ! -f "$file" ]; then

                        echo "ERROR> The file '$file' doesn't exist!"

                        let "error+=1"

                fi

        done

        if [ "$error" != "0" ]; then

                echo

                echo "ERROR> There were $error errors encountered!"

                echo "ERROR> Check your file path and try again."

                exit 2

        fi

}

#check for directory presence on all selected servers

check_directory() {

        error=0

        echo "> Checking for directory presence ..."

        for server in $SERVERS_ALL; do

                ssh $USERNAME@$server ls -d $DIRECTORY > /dev/null 2>&1

                if [ "$?" != "0" ]; then

                        echo "ERROR> The directory '$DIRECTORY' doesn't exist on '$server'"

                        let "error+=1"

                fi

        done

        if [[ "$error" != "0" && "$CREATE_FOLDER" == "0" ]]; then

                echo

                echo "ERROR> There were $error errors encountered!"

                echo "ERROR> Check your directory path or active 'CREATE_FOLDER' option in this script."

                exit 2

        fi

}

#do the job!

do_it() {

        check_file

        if [ "$CREATE_FOLDER" != "1" ]; then

                check_directory

        fi

        echo "> All is okay, starting upload ..."

        for server in $SERVERS_ALL; do

                echo ">>> working on '$server' ..."

                if [ "$CREATE_FOLDER" == "1" ]; then

                        ssh $USERNAME@$server "mkdir -p $DIRECTORY" > /dev/null 2>&1

                fi

                scp $FILES $USERNAME@$server:$DIRECTORY

        done

}

#print help

print_help() {

        echo "HELP> Command line syntax :"

        echo "HELP> ssh_remote_file_copy [--do-it] <directory> <file1> [file2] [...]"

}

#looking for switch in the command line

# --do-it : do the job!

search_param() {

        ACTION="no"

        counter=0

        counter2=0

        for word in $@; do

                if [ "$word" == "--do-it" ]; then

                        ACTION="yes"

                else

                        DIRECTORY="$word"

                        break

                fi

                let "counter+=1"

        done

        for word in $@; do

                if [ $counter2 -gt $counter ]; then

                        FILES="$FILES $word"

                fi

                let "counter2+=1"

        done

}

#MAIN---------------------------------------------------------------------------------------

search_param "$@"

if [[ "$1" == "" || "$DIRECTORY" == "" || "$FILES" == "" ]]; then

        print_help

elif [ "$ACTION" != "yes" ]; then

        summary

else

        do_it

fi

echo

echo "> Done"
```

Voilou, ce sera peut être plus simple ainsi .. Voyez la fonction "search_param" ... elle "craint" je trouve :/     et avec tout ca, "--do-it" ne peut être QUE après le nom du script  :Sad:    bref, ca crain

----------

## xaviermiller

Salut,

As-tu essayé getopt ?

Et shift dans une fonction ?

----------

## loopx

 *XavierMiller wrote:*   

> Salut,
> 
> As-tu essayé getopt ?
> 
> Et shift dans une fonction ?

 

getopt, c'est, d'après le peu que j'ai lu, uniquement 1 lettre pour le paramètre ...

Sinon, l'idée du shift est plus que bonne pour les fonctions, comment n'y ais-je pas penser plus tot  :Surprised: 

----------

## xaviermiller

Salut,

Getopt a les options longues et courtes.

C'est à la base de quasi tout ce qui a des options chez GNU (je peux me tromper...)

----------

## loopx

 *XavierMiller wrote:*   

> Salut,
> 
> Getopt a les options longues et courtes.
> 
> C'est à la base de quasi tout ce qui a des options chez GNU (je peux me tromper...)

 

IL fautdra que je test alors  :Smile: 

Pour l'instant, j'ai remplacer la fonction "search_param" par ceci (qui est plus esthétique ^^) :

```
search_param() {

        ACTION="no"

        for word in $@; do

                if [ "$word" == "--do-it" ]; then

                        ACTION="yes"

                else

                        DIRECTORY="$word"

                        break

                fi

                #remove first parameter if needed (when --do-it)

                shift

        done

        #remove second parameter to just let files

        shift

        FILES=$@

}
```

EDIt: script dispo ici, ceux que ca pourrait intéresser  :Wink:  :

http://pix-mania.dyndns.org/mediawiki/index.php/OpenSSH_-_script_d'envoi_de_fichiers

----------

