2008-09-15 6 views
1

Je souhaite utiliser un fichier pour stocker le numéro de version actuel d'un logiciel client pouvant être utilisé par un script de démarrage pour exécuter le fichier binaire dans le bon répertoire.Quel est le meilleur moyen d'extraire une chaîne de version à partir d'un fichier?

Par exemple, si le répertoire d'exécution ressemble à ceci:

. 
.. 
1.2.1 
1.2.2 
1.3.0 
run.sh 
current_version 

Et current_version contient:

1.2.2 

Je veux run.sh descendre dans 1.2.2 et exécuter le programme foo.

La solution actuelle est la suivante:

#!/bin/sh 
version = `cat current_version` 
cd $version 
./foo 

Il fonctionne mais pas très robuste. Il ne vérifie pas l'existence des fichiers, ne peut pas gérer plusieurs lignes, espaces de début, lignes commentées, fichiers vides, etc.

Quelle est la manière la plus fiable de faire cela avec un script shell ou perl?

Répondre

5

C'est une approche courante. Vous pouvez vérifier l'existence du répertoire/fichier en utilisant des opérateurs de test tels que "if [-d" somedirectory "], puis" ou [-t "somefile"]

J'utilise plus souvent des liens symboliques. Ensuite, vous pouvez simplement changer votre lien symbolique pour utiliser la version que vous voulez.

Par exemple,

 
$ ln -s 1.2.2 current_version 
$ ls -al 
total 20 
drwxr-xr-x 5 dbreese dbreese 4096 2008-09-15 13:34 . 
drwxr-xr-x 3 dbreese dbreese 4096 2008-09-15 13:34 .. 
drwxr-xr-x 2 dbreese dbreese 4096 2008-09-15 13:34 1.2.1 
drwxr-xr-x 2 dbreese dbreese 4096 2008-09-15 13:34 1.2.2 
drwxr-xr-x 2 dbreese dbreese 4096 2008-09-15 13:34 1.3.0 
lrwxrwxrwx 1 dbreese dbreese 6 2008-09-15 13:34 current_version -> 1.2.2/ 

Ensuite, votre script peut utiliser "cd current_version".

+0

Je veux éviter les liens parce que Je ne veux pas perturber les instances existantes du programme qui pourraient s'opposer à ce que leur répertoire de travail soit modifié. – Frosty

0

Je voudrais changer le script pour accepter un argument. L'argument devrait être un nom de fichier. Ouvrez le fichier en utilisant le langage de script que vous préférez [perl, python] et parcourez le fichier jusqu'à ce que vous trouviez une correspondance pour votre version.

J'utiliserais une regex ... quelque chose le long des lignes de /\d\.\d\.\d/. alors faites-le exécuter l'application à travers votre script.

+0

Une bonne solution mais il n'y a aucune garantie que la version restera x.x.x. Les nombres mineurs pourraient dépasser 9 et donner quelque chose comme 1.2.12 qui échouerait. – Frosty

+0

@Frosty Peut-être que /\d+\.\d+\.\d+/ servirait dans ce cas? –

0

Vous pouvez vérifier la présence à l'aide de & & et de || opérateurs:

 
!$/bin/sh 
version = `cat current_version` 
cd $version && ./foo || echo "Bad version" 

L'opérateur & & provoque la deuxième instruction à exécuter que si le premier réussit (état de sortie 0), et les || L'opérateur provoque l'exécution de la seconde instruction uniquement si la première échoue (état de sortie différent de zéro).

Je ne suis pas sûr de savoir ce que vous voulez dire en faisant face à plusieurs lignes, espaces principaux ou lignes commentées.

+0

Je voudrais gérer avec élégance des fichiers de version légèrement "incorrects". Si le fichier avait deux lignes, un espace de début, un espace de fin ou quelque chose comme ça, la solution originale échouerait. – Frosty

-4
!#/bin/sh 

if [ -e 'current_version' ]; then 
    version=`cat current_version`; 
    version=`echo $version | tr -ds [[:blank:]]` 
    if [ -n "$version" ]; then 
     if [ -d "$version" ]; then 
     cd "$version" 
     else 
     echo $version is not a directory 
     fi 
    else 
     echo version_file contained only blanks 
    fi 
else 
    No file named current_version exists 
fi 
+0

Cela échouera sauf s'il existe un répertoire nommé $ version. '$ version' retournera toujours la chaîne $ version et ne développera jamais la variable. Utilisez plutôt des guillemets doubles: "$ version". –

0

Si le versionnement sera toujours en #. #.# Format, vous pouvez le faire:

ls | grep ^[0-9]\.[0-9]\.[0-9]$ | sort -nr | head -n 1 

qui liste les versions en ordre numérique descendant, sélectionne alors le premier de ceux

+0

Aucune garantie sur le numéro de version. De plus, j'aimerais pouvoir retourner current_version dans le cas où la dernière version s'avère instable. Il serait peut-être préférable de combiner une sorte de grep avec la solution proposée. – Frosty

0

Qu'en est-:

#!/usr/bin/perl -w 
use strict; 
use warnings; 

my $version_file = 'current_version'; 
open my $fh, '<', $version_file or die "Can't open $version_file: $!"; 

# Read version from file 
my $version = <$fh>; 
chomp $version; 

# Remove whitespace (and match version) 
die "Version format not recognized" if $version !~ m/(\d+\.\d+\.\d+)/; 

my $dir = $1; 
die "Directory not found: $dir" unless -d $dir; 

# Execute program in versioned directory. 
chdir $dir; 
system("./foo"); 
Questions connexes