it-swarm.com.ru

Сценарий оболочки не запущен, команда не найдена

Я очень, очень плохо знаком с программированием в UNIX (работаю на MacOSX Mountain Lion через Terminal). Я изучал основы из курса биоинформатики и молекулярных методов (у нас было два класса), где мы в конечном итоге будем использовать Perl и python для целей управления данными. В любом случае, перед нами была поставлена ​​задача написать сценарий Shell, чтобы взять данные из группы файлов и записать их в новый файл в формате, который может быть прочитан определенной программой (Migrate-N). 

Я получил ряд функций, чтобы делать именно то, что мне нужно, независимо, когда я набираю их в командной строке, но когда я складываю их все вместе в сценарии и пытаюсь запустить его, я получаю сообщение об ошибке. Вот подробности (прошу прощения за длину):

#! /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

Серия greps просто извлекает данные последовательности ДНК для каждого сайта для каждого локуса в новые текстовые файлы. Файлы Samples ... txt содержат идентификационные номера образцов для сайта, файлы .fasta содержат информацию о последовательности, упорядоченную по идентификатору образца; grepping прекрасно работает в командной строке, если я запускаю его по отдельности. 

Вторая группа кода создает фактический новый файл, который мне нужен, который заканчивается на .mig. Линии эха - это данные о количестве (базовые пары на локус, популяции в анализе, выборки на участок и т.д.), По которым программе требуется информация. Линии кошки должны объединять локус с помощью данных сайта, созданных всеми данными ниже информации, специфичной для сайта, которая определяется в строке эха. Вы, без сомнения, получите картину.

Для создания сценария оболочки я начал в Excel, поэтому я могу легко копировать-вставлять/автозаполнять ячейки, сохраняя текст с разделителями табуляции, а затем открывая этот текстовый файл в TextWrangler, чтобы удалить вкладки перед сохранением в виде файла .sh (строка перерывы: Unix (LF) и Encoding: Unicode (UTF-8)) в том же каталоге, что и все файлы, используемые в сценарии. Я пытался использовать chmod +x FILENAME.sh и chmod u+x FILENAME.sh, чтобы убедиться, что он исполняемый, но безрезультатно. Даже если я урежу скрипт до одной строки grep (с первой строкой #!/Bin/bash), я не смогу заставить его работать. Процесс занимает всего минуту, когда я набираю его непосредственно в командной строке, поскольку ни один из этих файлов не превышает 160 КБ, а некоторые значительно меньше. Это то, что я печатаю и что получаю, когда пытаюсь запустить файл (HW - правильный каталог)

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

Я был в этом тупике в течение двух дней, поэтому любой вклад будет принята с благодарностью! Спасибо!!

21
ChickadeeChick

По соображениям безопасности оболочка не будет искать в текущем каталоге (по умолчанию) исполняемый файл. Вы должны быть конкретны и сообщить bash, что ваш скрипт находится в текущем каталоге (.):

$ ./MigrateNshell.sh
32
chepner

Измените первую строку на следующую, как указал Марк Б

#!/bin/bash 

Затем пометьте скрипт как исполняемый и выполните его из командной строки

chmod +x MigrateNshell.sh
./MigrateNshell.sh

или просто выполните bash из командной строки, передав в сценарии в качестве параметра

/bin/bash MigrateNshell.sh
17
Ryan Williams

Убедитесь, что вы не используете «PATH» в качестве переменной, которая переопределит существующий PATH для переменных среды.

9
janhavi

Также попробуйте dos2unix сценарий Shell, потому что иногда он имеет окончания строки Windows, и Shell не распознает его.

$ dos2unix MigrateNshell.sh

Это помогает иногда.

7
Adolfo

Было несколько хороших комментариев по поводу добавления строки Shebang в начало скрипта. Я хотел бы добавить рекомендацию по использованию команды env ​​ для дополнительной переносимости.

Хотя #!/bin/bash может быть правильным местоположением в вашей системе, это не универсально. Кроме того, это не может быть пользовательский {предпочтительно bash. #!/usr/bin/env bash выберет первый bash, найденный в пути.

2
broadmonkey

Попробуйте chmod u+x MigrateNshell.sh

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

удалить указанное место. Шебанг должен быть

#!/bin/bash
1
Marc B

В Unix есть переменная PATH, которая представляет собой список каталогов, в которых можно найти команды.

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

Если я введу команду foo в командной строке, моя оболочка сначала увидит, есть ли исполняемая команда /usr/local/bin/foo. Если есть, он будет выполнять /usr/local/bin/foo. Если нет, он увидит, есть ли исполняемая команда /usr/bin/foo, а если ее нет, то посмотрит, существует ли /bin/foo и т.д., Пока не доберется до /Users/david/bin/foo.

Если он не может найти команду foo ни в одном из этих каталогов, он сообщает мне команда не найдена .

Есть несколько способов справиться с этой проблемой:

  • Используйте команду bash foo, поскольку foo является сценарием оболочки.
  • Включите имя каталога, когда вы выполняете команду, например /Users/david/foo или $PWD/foo или просто ./foo.
  • Измените переменную $PATH, чтобы добавить каталог, содержащий ваши команды, в переменную PATH.

Вы можете изменить $HOME/.bash_profile или $HOME/.profile, если .bash_profile не существует. Я сделал это, чтобы добавить /usr/local/bin, который я поместил первым на моем пути. Таким образом, я могу переопределить стандартные команды, которые есть в ОС. Например, у меня есть Ant 1.9.1, но Mac поставляется с Ant 1.8.4. Я поместил свою команду ant в /usr/local/bin, поэтому моя версия ant будет выполняться первой. Я также добавил $HOME/bin в конец PATH для своих собственных команд. Если бы у меня был файл, подобный тому, который вы хотите выполнить, я поместил бы его в $ HOME/bin, чтобы выполнить его.

1
David W.

Также убедитесь, что/bin/bash является правильным местом для bash .... если вы взяли эту строку из примера где-то, она может не соответствовать вашему конкретному серверу. Если вы указываете неверное местоположение для bash, у вас возникнут проблемы.

0
James Gawron

Добавьте строки ниже в ваш путь .profile

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

export PATH

Теперь ваш скрипт должен работать без ./

Радж Дагла

0
Raj Dagla

Я новичок в сценариях Shell, но у меня была та же проблема. Убедитесь, что в конце вашего скрипта у вас есть пустая строка. Иначе это не сработает.

0
A Smith