Ответ 1
Из соображений безопасности оболочка не будет искать текущий каталог (по умолчанию) для исполняемого файла. Вы должны быть конкретными и сообщить bash
, что ваш script находится в текущем каталоге (.
):
$ ./MigrateNshell.sh
Я очень, очень новичок в программировании UNIX (работает на MacOSX Mountain Lion через Terminal). Я изучал основы курса биоинформатики и молекулярных методов (у нас было два класса), где мы в конечном итоге будем использовать perl и python для целей управления данными. В любом случае нам было поручено написать оболочку script, чтобы взять данные из группы файлов и записать их в новый файл в формате, который может быть прочитан определенной программой (Migrate-N).
У меня есть ряд функций для выполнения того, что мне нужно независимо, когда я ввожу их в командную строку, но когда я их объединяю в script и пытаюсь запустить, я получаю сообщение об ошибке. Вот подробности (извиняюсь за длину):
#! /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 просто вытаскивает данные последовательности ДНК для каждого сайта для каждого локуса в новые текстовые файлы. В образцах... txt есть идентификационные номера образцов для сайта, файлы .fasta имеют информацию о последовательности, организованную с помощью идентификатора образца; grepping отлично работает в командной строке, если я запускаю его по отдельности.
Вторая группа кода создает фактический новый файл, в котором я должен закончить, заканчивающийся на .mig. Эхо-строки - это данные о подсчетах (базовые пары для каждого локуса, популяции в анализе, образцы на сайт и т.д.), О которых программа нуждается в информации. Строки cat заключаются в том, чтобы смять локус по данным сайта, созданным всеми grepping, ниже информации о сайте, продиктованной эхо-линией. Вы, несомненно, получите картину.
Для создания оболочки script я запускаюсь в Excel, поэтому я могу легко копировать/вставлять/автозавершать ячейки, сохраняя в виде текста с разделителями табуляции, а затем открывая этот текстовый файл в TextWrangler, чтобы удалить вкладки перед сохранением в качестве .sh(Разрывы строк: Unix (LF) и Кодировка: Unicode (UTF-8)) в том же каталоге, что и все файлы, используемые в script. Я попытался использовать chmod +x FILENAME.sh
и chmod u+x FILENAME.sh
, чтобы убедиться, что он является исполняемым, но безрезультатно. Даже если я разрежу script до единственной строки grep (с первой строкой #!/Bin/bash), я не могу заставить ее работать. Процесс занимает всего лишь один момент, когда я ввожу его непосредственно в командную строку, так как ни один из этих файлов не превышает 160 КБ, а некоторые значительно меньше. Это то, что я набираю и что получаю, когда пытаюсь запустить файл (HW - правильный каталог)
localhost:HW Mirel$ MigrateNshell.sh
-bash: MigrateNshell.sh: command not found
Я был на этом тупике уже два дня, поэтому любой вклад был бы очень признателен! Спасибо!!
Из соображений безопасности оболочка не будет искать текущий каталог (по умолчанию) для исполняемого файла. Вы должны быть конкретными и сообщить bash
, что ваш script находится в текущем каталоге (.
):
$ ./MigrateNshell.sh
Измените первую строку на следующую, как указано Marc B
#!/bin/bash
Затем отметьте script как исполняемый файл и выполните его из командной строки
chmod +x MigrateNshell.sh
./MigrateNshell.sh
или просто выполните bash из командной строки, проходящей в вашем script в качестве параметра
/bin/bash MigrateNshell.sh
Убедитесь, что вы не используете "PATH" в качестве переменной, которая переопределит существующие переменные PATH для переменных среды.
Также попробуйте dos2unix
оболочку script, потому что иногда она имеет окончания строки Windows, и оболочка ее не распознает.
$ dos2unix MigrateNshell.sh
Иногда это помогает.
Было несколько хороших комментариев о добавлении env, для дополнительной портативность.
Хотя #!/bin/bash
может быть правильным местом в вашей системе, это не универсально. Кроме того, это может быть не предпочтительнее пользователя bash. #!/usr/bin/env bash
выберет первый bash, найденный в пути.
#! /bin/bash
^---
удалите указанное пространство. Shebang должен быть
#!/bin/bash
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
- это оболочка script./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 для его выполнения.
Также убедитесь, что /bin/ bash является подходящим местом для bash.... если вы взяли эту строку из примера где-то, она может не соответствовать вашему конкретному серверу. Если вы указали неверное местоположение для bash, у вас возникнет проблема.
Добавьте ниже строки в свой путь .profile
PATH=$PATH:$HOME/bin:$Dir_where_script_exists
export PATH
Теперь ваш script должен работать без ./
Радж Дагла
Попробуйте chmod u+x MigrateNshell.sh
Во-первых:
chmod 777 ./MigrateNshell.sh
Тогда:
./MigrateNshell.sh
Или добавьте свою программу в каталог, распознанный в переменной $PATH. Пример: Пример переменной пути
Затем вы сможете называть свою программу без ./