Scripts Bash à faire
J'ai un makefile que j'utilise pour exécuter de simples scripts bash à l'intérieur d'une mise en pension, je travaille sur. Je suis tenter de faire un nouveau faire appel qui va me connecter à ma base de données mySQL automatiquement. J'ai mon nom d'utilisateur et le mot de passe stocké dans un .zinfo fichier à un emplacement connu (comme "/u/r/z/myid/.zinfo"). J'essaie de lire les lignes de ce fichier afin d'obtenir mon mot de passe, ce qui est de la forme:
user = csj483
database = cs495z_csj483
password = fjlID9dD923
Voici le code, je suis en train de lancer, depuis le makefile, mais ça ne fonctionne pas. Si j'exécute le même code directement dans le shell, il semble bien fonctionner. Note que j'ai eu à utiliser la double $$s parce que faire n'aime pas le seul.
login:
for line in $$(cat /u/z/users/cs327e/$$USER/.zinfo); \
do \
PASSWORD=$$line; \
echo $$PASSWORD; \
done
echo $$PASSWORD
À ce point, je suis juste essayer d'obtenir le mot de passe, ce qui devrait être la dernière valeur que le MOT de passe est défini dans la boucle. Si tout le monde peut proposer un moyen plus facile de récupérer le mot de passe ou mon erreur dans mon code, je l'apprécierais. Finalement, je tiens également à récupérer le nom de la base en tant que bien, et tout vous venir en aide serait appréciée. Je suis nouveau sur le bash, mais expérimentée dans de nombreuses autres langues.
OriginalL'auteur user2300448 | 2013-04-19
Vous devez vous connecter pour publier un commentaire.
Vous ne spécifiez pas ce que vous voulez dire par "ne pas travailler"; pour poser des questions s'il vous plaît toujours être très clair sur la commande que vous avez tapé, le résultat que vous avez obtenu (couper-coller), et pourquoi ce n'est pas ce que vous attendiez.
De toute façon, la plupart probable que le comportement que vous voyez n'est que la première écho montre la sortie que vous attendez, mais le second ne l'est pas. C'est parce que
make
appelle chaque ligne logique dans la recette dans un séparé shell. Ainsi, la boucle est exécuté dans un shell, et il définit la variable d'environnementPASSWORD
, alors que shell s'arrête et le dernierecho
est exécuté dans un nouveau shell... oùPASSWORD
n'est plus définie.Vous avez besoin de mettre l'intégralité de la ligne de commande dans une logique unique de la ligne dans la recette:
Une dernière chose à retenir: vous dites que vous êtes l'exécution de scripts bash, mais faire ne pas exécuter bash. Il fonctionne
/bin/sh
, indépendamment de ce que shell que vous utilisez (imaginez le carnage si les makefiles utilisés quel que soit le shell de l'utilisateur qui est arrivé à être à l'aide!). Votre meilleure option est d'écrire des recettes portable syntaxe shell. Si vraiment vous ne pouvez pas le faire, assurez-vous de définirSHELL := /bin/bash
dans votreMakefile
pour forcer l'usage de bash.ETA:
Concernant votre question, vous avez beaucoup d'options. Si vous avez le contrôle sur le format de la zinfo fichier à tous, alors je vous invite à le définir à utiliser la même syntaxe que la coquille de la définition des variables. Dans l'exemple ci-dessus si vous avez supprimé les espaces autour de la
=
signe, comme ceci:Alors vous avez un script shell valide avec les affectations de variables. Maintenant, vous pouvez source de ce script dans votre makefile et votre vie est TRÈS simple:
Si vous n'avez pas de contrôle sur la syntaxe de la zinfo fichier puis la vie est plus difficile. Vous pouvez utiliser la fonction eval, quelque chose comme ceci:
Cette version ne fonctionne que si il y a des espaces autour du signe "=". Si vous souhaitez soutenir à la fois que c'est possible.
J'ai eu la connexion fonctionne correctement à l'aide de la première suggestion, simplement en ajoutant de l' && à ma dernière ligne, mais j'ai essayé le dernier bloc et lors de l'exécution, il dit simplement: "rien à faire pour "login". J'ai ajouté une déclaration à la fin qui est un appel à mysql comme je l'ai fait pour le premier exemple. Une idée de ce qui se passe là-bas?
Il est difficile de suivre votre description: si vous avez mis à jour votre question avec le makefile de la règle qu'il serait plus simple. Cependant, un message de la forme rien à faire pour XXX signifie que faire pense que la cible XXX est jusqu'à ce jour. Depuis votre
login
cible a pas de pré-requis, il sera considéré jusqu'à ce jour si la cible existe. Donc, je dirais que vous avez un fichier dans votre répertoire nommélogin
. Soit de supprimer ce fichier ou, mieux, de déclarer lalogin
cible faux par l'ajout de.PHONY: login
à votre makefile.Ce qui est si bon d'avoir le script en shell POSIX? Il y a bash sur la plupart des systèmes à cet âge, et à l'aide de fonctionnalités de bash pourrait rendre le code plus clair.
"La plupart des systèmes" est relative. Il n'est souvent pas disponible sur les systèmes *BSD, pas sur Solaris, pas sur d'autres systèmes GNU/Linux. Il n'est souvent pas disponible sur les systèmes les plus petits (bien que, certes, la plupart ne fonctionnent pas faire). Aussi, quelle est la version de bash? Pas toutes les versions en charge toutes les fonctionnalités, et les plus âgés, mais toujours pris en charge les systèmes GNU/Linux viennent avec les anciennes versions de bash. Il est plus simple d'utiliser POSIX sh. Si vous êtes à la rédaction d'un makefile recette assez compliqué qui pourrait vraiment profiter de fonctionnalités de bash, vous devriez reconsidérer votre mise en œuvre de toute façon.
OriginalL'auteur MadScientist