web-dev-qa-db-fra.com

Script shell non en cours d'exécution, commande introuvable

Je suis très, très nouveau dans la programmation UNIX (fonctionnant sous MacOSX Mountain Lion via Terminal). J'ai appris les bases d'un cours de bioinformatique et de méthodes moléculaires (nous avons eu deux cours) où nous utiliserons éventuellement Perl et python à des fins de gestion de données. Quoi qu’il en soit, nous avons été chargés d’écrire un script Shell pour extraire des données d’un groupe de fichiers et les écrire dans un nouveau fichier dans un format pouvant être lu par un programme spécifique (Migrate-N). 

J'ai eu un certain nombre de fonctions pour faire exactement ce dont j'ai besoin quand je les tape dans la ligne de commande, mais quand je les rassemble toutes dans un script et que je tente de l'exécuter, j'obtiens une erreur. Voici les détails (je m'excuse pour la longueur):

#! /bin/bash

grep -f Samples.NFCup.txt locus1.fasta > locus1.NFCup.txt
grep -f Samples.NFCup.txt locus2.fasta > locus2.NFCup.txt
grep -f Samples.NFCup.txt locus3.fasta > locus3.NFCup.txt
grep -f Samples.NFCup.txt locus4.fasta > locus4.NFCup.txt
grep -f Samples.NFCup.txt locus5.fasta > locus5.NFCup.txt
grep -f Samples.Salmon.txt locus1.fasta > locus1.Salmon.txt
grep -f Samples.Salmon.txt locus2.fasta > locus2.Salmon.txt
grep -f Samples.Salmon.txt locus3.fasta > locus3.Salmon.txt
grep -f Samples.Salmon.txt locus4.fasta > locus4.Salmon.txt
grep -f Samples.Salmon.txt locus5.fasta > locus5.Salmon.txt
grep -f Samples.Cascades.txt locus1.fasta > locus1.Cascades.txt
grep -f Samples.Cascades.txt locus2.fasta > locus2.Cascades.txt
grep -f Samples.Cascades.txt locus3.fasta > locus3.Cascades.txt
grep -f Samples.Cascades.txt locus4.fasta > locus4.Cascades.txt
grep -f Samples.Cascades.txt locus5.fasta > locus5.Cascades.txt

echo 3 5 Salex_melanopsis > Smelanopsis.mig
echo 656 708 847 1159 779 >> Smelanopsis.mig
echo 154 124 120 74 126 NFCup >> Smelanopsis.mig
cat locus1.NFCup.txt locus2.NFCup.txt locus3.NFCup.txt locus4.NFCup.txt locus5.NFCup.txt >> Smelanopsis.mig
echo 32 30 30 18 38 Salmon River >> Smelanopsis.mig
cat locus1.Salmon.txt locus2.Salmon.txt locus3.Salmon.txt locus4.Salmon.txt locus5.Salmon.txt >> Smelanopsis.mig
echo 56 52 24 29 48 Cascades >> Smelanopsis.mig
cat locus1.Cascades.txt locus2.Cascades.txt locus3.Cascades.txt locus4.Cascades.txt locus5.Cascades.txt >> Smelanopsis.mig

La série de greps extrait simplement les données de séquence d'ADN de chaque site pour chaque locus dans de nouveaux fichiers texte. Les exemples ... Les fichiers txt ont les numéros d'identification des échantillons pour un site, les fichiers .fasta ont les informations de séquence organisées par ID d'échantillons; le grepping fonctionne très bien en ligne de commande si je le lance individuellement. 

Le deuxième groupe de code crée le nouveau fichier que je dois terminer, qui se termine par .mig. Les lignes d'écho sont des données sur les comptages (paires de bases par lieu, populations dans l'analyse, échantillons par site, etc.) pour lesquels le programme a besoin d'informations. Les lignes de cat doivent écraser ensemble le locus par les données de site créées par tous les grepings situés sous les informations spécifiques au site dictées dans la ligne d'écho. Vous avez sans doute la photo.

Pour créer le script Shell, je me suis lancé dans Excel afin de pouvoir facilement copier-coller/remplir des cellules, enregistrer en tant que texte délimité par des tabulations, puis ouvrir ce fichier texte dans TextWrangler pour supprimer les onglets avant de les enregistrer sous forme de fichier .sh (Line). breaks: Unix (LF) et Encoding: Unicode (UTF-8)) dans le même répertoire que tous les fichiers utilisés dans le script. J'ai essayé d'utiliser chmod +x FILENAME.sh et chmod u+x FILENAME.sh pour essayer de m'assurer qu'il est exécutable, mais en vain. Même si je réduisais le script à une seule ligne grep (avec la première ligne #!/Bin/bash), je ne pouvais pas le faire fonctionner. Le processus ne prend que quelques instants lorsque je le tape directement dans la ligne de commande, car aucun de ces fichiers ne dépasse 160 Ko et certains sont considérablement plus petits. C’est ce que je tape et ce que je reçois quand j’essaie d’exécuter le fichier (HW est le bon répertoire)

localhost:HW Mirel$ MigrateNshell.sh
-bash: MigrateNshell.sh: command not found

Cela fait deux jours que je suis dans cette impasse, toute contribution serait grandement appréciée! Merci!!

21
ChickadeeChick

Pour des raisons de sécurité, le shell ne cherchera pas dans le répertoire en cours (par défaut) un exécutable. Vous devez être spécifique et indiquer à bash que votre script se trouve dans le répertoire en cours (.):

$ ./MigrateNshell.sh
32
chepner

Changer la première ligne comme suit, comme l'a souligné Marc B.

#!/bin/bash 

Marquez ensuite le script comme exécutable et exécutez-le à partir de la ligne de commande.

chmod +x MigrateNshell.sh
./MigrateNshell.sh

ou exécutez simplement bash depuis la ligne de commande en transmettant votre script en tant que paramètre

/bin/bash MigrateNshell.sh
17
Ryan Williams

Assurez-vous de ne pas utiliser "PATH" en tant que variable, qui remplacera le PATH existant pour les variables d'environnement.

9
janhavi

Essayez également de dos2unix le script Shell, car il comporte parfois des fins de ligne Windows et le shell ne le reconnaît pas.

$ dos2unix MigrateNshell.sh

Cela aide parfois.

7
Adolfo

Il y a eu quelques bons commentaires sur l'ajout de la ligne Shebang au début du script. Je voudrais ajouter une recommandation pour utiliser la commande env ​​ également, pour une portabilité supplémentaire.

Bien que #!/bin/bash puisse être l'emplacement correct sur votre système, ce n'est pas universel. En outre, il se peut que l'utilisateur ne soit pas préféré bash. #!/usr/bin/env bash sélectionnera le premier bash trouvé dans le chemin.

2
broadmonkey

Essayez chmod u+x MigrateNshell.sh

2
Aminah Nuraini
#! /bin/bash
  ^---

supprimez l'espace indiqué. Le Shebang devrait être

#!/bin/bash
1
Marc B

Unix a une variable appelée PATH qui est une liste de répertoires où trouver des commandes.

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/david/bin

Si je tape une commande foo sur la ligne de commande, mon shell va d'abord voir s'il existe une commande exécutable /usr/local/bin/foo. Si c'est le cas, il exécutera /usr/local/bin/foo. Sinon, il verra s'il y a une commande exécutable /usr/bin/foo et s'il n'y en a pas, il regardera si /bin/foo existe, etc. jusqu'à ce qu'il atteigne /Users/david/bin/foo.

S'il ne peut pas trouver une commande foo dans l'un de ces répertoires, il me dit commande non trouvée .

Je peux gérer ce problème de plusieurs manières:

  • Utilisez la commandebash foo puisque foo est un script Shell.
  • Incluez le nom du répertoire lorsque vous exécutez la commande telle que /Users/david/foo ou $PWD/foo ou tout simplement ./foo.
  • Modifiez votre variable $PATH pour ajouter le répertoire contenant vos commandes au PATH.

Vous pouvez modifier $HOME/.bash_profile ou $HOME/.profile si .bash_profile n'existe pas. Je l'ai fait pour ajouter dans /usr/local/bin que j'ai placé en premier sur mon chemin. De cette façon, je peux remplacer les commandes standard présentes dans le système d'exploitation. Par exemple, j'ai Ant 1.9.1, mais le Mac est venu avec Ant 1.8.4. Je mets ma commande ant dans /usr/local/bin afin que ma version de ant s'exécute en premier. J'ai aussi ajouté $HOME/bin à la fin du PATH pour mes propres commandes. Si j'avais un fichier comme celui que vous voulez exécuter, je le placerai dans $ HOME/bin pour l'exécuter.

1
David W.

Assurez-vous également que/bin/bash est le bon emplacement pour bash .... si vous prenez cette ligne à partir d'un exemple, elle risque de ne pas correspondre à votre serveur. Si vous spécifiez un emplacement non valide pour bash, vous allez avoir un problème.

0
James Gawron

Ajouter les lignes ci-dessous dans votre chemin .profile

PATH=$PATH:$HOME/bin:$Dir_where_script_exists

export PATH

Maintenant, votre script devrait fonctionner sans ./

Raj Dagla

0
Raj Dagla

Je suis également nouveau dans les scripts Shell, mais j'ai eu le même problème. Assurez-vous qu'à la fin de votre script, vous avez une ligne vide. Sinon, ça ne marchera pas.

0
A Smith