2013-05-13 15 views
15

Sono molto, molto nuovo alla programmazione UNIX (in esecuzione su MacOSX Mountain Lion tramite terminale). Ho imparato le nozioni di base da un corso di bioinformatica e metodi molecolari (abbiamo avuto due classi) in cui alla fine utilizzeremo perl e python per scopi di gestione dei dati. Ad ogni modo, abbiamo avuto il compito di scrivere uno script di shell per prendere i dati da un gruppo di file e scriverlo su un nuovo file in un formato che può essere letto da un programma specifico (Migrate-N).Newbie UNIX: script di shell non in esecuzione, comando non trovato

Ho ottenuto un certo numero di funzioni per fare esattamente ciò di cui ho bisogno autonomamente quando li digito nella riga di comando, ma quando li metto tutti insieme in uno script e provo a eseguirlo, ricevo un errore. Ecco i dettagli (mi scuso per la lunghezza):

#! /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 serie di greps sono solo tirando fuori i dati di sequenza del DNA per ogni sito per ogni locus in nuovi file di testo. I file Samples ... txt hanno i numeri ID di esempio per un sito, i file .fasta hanno le informazioni sulla sequenza organizzate dall'ID campione; il grepping funziona bene a riga di comando se lo eseguo individualmente.

Il secondo gruppo di codice crea il nuovo file effettivo con cui devo finire, che termina con .mig. Le linee dell'eco sono dati relativi ai conteggi (basi di riferimento per locus, popolazioni nell'analisi, campioni per sito, ecc.) Di cui il programma necessita informazioni. Le linee del gatto devono combinare il locus per i dati del sito creati da tutti i grepping al di sotto delle informazioni specifiche del sito dettate nella linea dell'eco. Senza dubbio ottieni l'immagine.

Per creare lo script di shell sono stato iniziando in Excel in modo da poter facilmente copia-incolla/cellule riempimento automatico, il risparmio come testo delimitato da tabulazioni, poi aprire il file di testo in TextWrangler per rimuovere le schede prima di salvare come. sh file (Interruzioni di riga: Unix (LF) e Codifica: Unicode (UTF-8)) nella stessa directory di tutti i file utilizzati nello script. Ho provato a utilizzare chmod +x FILENAME.sh e chmod u+x FILENAME.sh per cercare di assicurarmi che sia eseguibile, ma senza successo. Anche se riduco la sceneggiatura a una sola riga di grep (con la prima riga #!/Bin/bash) non riesco a farla funzionare. Il processo richiede solo un momento in cui lo digito direttamente nella riga di comando poiché nessuno di questi file è più grande di 160 KB e alcuni sono significativamente più piccoli. Questo è quello che ho tipo e cosa ottengo quando provo a eseguire il file (HW è la directory corretta)

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

Sono stato in questa impass da due giorni, in modo che qualsiasi ingresso sarebbe molto apprezzato ! Grazie!!

+3

è la posizione del 'MigrateNshell.sh' nel vostro' path'? Se provi a eseguirlo dalla directory corrente, prova "./MigrateNshell.sh". –

risposta

1

rimuovere lo spazio indicato. La faccenda dovrebbe essere

#!/bin/bash 
+6

Uno spazio è generalmente tollerato dopo l'hashbang. – chepner

+0

Vedere anche [questa risposta] (http://stackoverflow.com/a/10197964/3266847). –

28

Per motivi di sicurezza, la shell non cercherà la directory corrente (per impostazione predefinita) per un file eseguibile. Devi essere specifici, e dire bash che lo script si trova nella directory corrente (.):

$ ./MigrateNshell.sh 
+0

+1 Penso che sarebbe la causa. – Kent

+2

È inoltre possibile specificare l'interprete: 'bash MigrateNshell.sh'. Funziona anche senza autorizzazioni di esecuzione. – Otaia

-3

Primo:

chmod 777 ./MigrateNshell.sh 

Poi:

./MigrateNshell.sh 

Oppure, aggiungi la tua programma in una directory riconosciuta nella variabile $ PATH.Esempio: Path Variable Example che consentirà poi di chiamare il vostro programma senza ./

+4

Crea quel 'chmod 755', non' chmod 777'. '777' dà il permesso di scrittura a tutti gli utenti del sistema. '755' ti dà piena autorizzazione, ma solo leggere ed eseguire per tutti gli altri. –

1

Unix ha una variabile chiamata PATH che è una lista di directory dove trovare i comandi.

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

Se digito il comando foo dalla riga di comando, la mia shell prima vedere se c'è un comando eseguibile /usr/local/bin/foo. Se c'è, eseguirà /usr/local/bin/foo. In caso contrario, vedrà se c'è un comando eseguibile /usr/bin/foo e se non ci sarà, vedrà se /bin/foo esiste, ecc. Fino a quando non arriva a /Users/david/bin/foo.

Se non riesce a trovare un comando foo in una di quelle directory, mi viene indicato il comando non trovato.

Ci sono diversi modi che posso gestire questo problema:

  • utilizzare il comando bash foo dal foo è uno script di shell.
  • Includere il nome della directory quando si esegue il comando come /Users/david/foo o $PWD/foo o semplicemente ./foo.
  • Modificare la variabile $PATH per aggiungere la directory che contiene i comandi al PERCORSO.

È possibile modificare o $HOME/.bash_profile$HOME/.profile se .bash_profile non esiste. L'ho fatto per aggiungere in /usr/local/bin che ho inserito per primo nel mio percorso. In questo modo, posso ignorare i comandi standard presenti nel sistema operativo. Ad esempio, ho Ant 1.9.1, ma il Mac è venuto con Ant 1.8.4. Ho inserito il comando ant in /usr/local/bin, quindi la mia versione di ant verrà eseguita per prima. Ho anche aggiunto $HOME/bin alla fine del PERCORSO per i miei comandi. Se avessi un file come quello che vuoi eseguire, lo metto in $ HOME/bin per eseguirlo.

14

Modificare la prima riga come segue come sottolinea Marc B

#!/bin/bash 

quindi contrassegnare lo script come eseguibile e eseguirlo dalla riga di comando

chmod +x MigrateNshell.sh 
./MigrateNshell.sh 

o eseguire semplicemente bash dal riga di comando che passa lo script come parametro

/bin/bash MigrateNshell.sh 
0

Verificare anche/bin/bash è il percorso corretto per bash .... se hai preso quella linea da un esempio da qualche parte potrebbe non corrispondere al tuo server particolare. Se stai specificando un percorso non valido per bash, avrai un problema.

7

Prova anche a dos2unix lo script di shell, perché a volte ha terminazioni di linea di Windows e la shell non lo riconosce.

$ dos2unix MigrateNshell.sh 

Questo aiuta a volte.

+0

Questo l'ha risolto per me. In questo caso ho potuto vedere il problema (dopo che questa risposta l'ha suggerito) notando in vi il^M aggiunto a ogni riga. Stranamente, Gvim pensava che fosse già il formato Unix, quindi doveva essere stata una riga singola che finiva male. – lessthanideal

+0

Stavo cercando ovunque ho dimenticato di aver modificato il file in Windows! – Omar

0

Aggiungi sotto le linee nel tuo.profilo percorso

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

export PATH 

Ora lo script dovrebbe funzionare senza ./

Raj Dagla

2

Ci sono stati un paio di buoni commenti su come aggiungere il shebang line all'inizio dello script. Vorrei aggiungere una raccomandazione per utilizzare lo env command, per una maggiore portabilità.

Mentre #!/bin/bash potrebbe essere la posizione corretta sul sistema, non è universale. Inoltre, potrebbe non essere il preferito dall'utente bash. #!/usr/bin/env bash selezionerà la prima bash trovata nel percorso.

9

Assicurarsi di non utilizzare "PATH" come variabile, che sostituirà il PATH esistente per le variabili di ambiente.

1

Prova chmod u+x MigrateNshell.sh