UNIX新手:shell脚本没有运行,找不到命令

我对UNIX编程非常非常陌生(通过terminal在MacOSX Mountain Lion上运行)。 我一直在从生物信息学和分子方法课程(我们有两个类)中学习基础知识,最终将使用perl和python进行数据pipe理。 无论如何,我们的任务是编写一个shell脚本,从一组文件中获取数据,并将其写入一个可以被特定程序(Migrate-N)读取的格式的新文件中。

当我将它们键入到命令行时,我已经获得了许多独立完成所需function的function,但是当我将它们放在脚本中并尝试运行时,出现错误。 这里是细节(我对这个长度表示歉意):

#! /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系列只是将每个位点的DNA序列数据提取到新的文本文件中。 Samples … txt文件具有站点的示例ID号,.fasta文件具有按样本ID组织的序列信息; 如果我单独运行它,grep在命令行中工作得很好。

第二组代码创build了我需要以.mig结尾的实际新文件。 回波线是程序需要信息的计数数据(每个基因座的碱基对,分析人群,每个站点的样本等)。 猫线将按照由回波线指定的站点特定信息下面的所有格点创build的站点数据将轨迹混合在一起。 你毫无疑问得到的图片。

为了创buildshell脚本,我已经在Excel中启动了,所以我可以轻松地复制粘贴/自动填充单元格,保存为制表符分隔的文本,然后在TextWrangler中打开该文本文件,将其保存为.sh文件之前删除标签(Line在与脚本中使用的所有文件相同的目录中打破:Unix(LF)和Encoding:Unicode(UTF-8))。 我已经尝试使用chmod +x FILENAME.shchmod u+x FILENAME.sh来尝试确保它是可执行的,但无济于事。 即使我把脚本简化为一个grep行(用#!/ bin / bash第一行),我也无法使它工作。 这个过程只需要一点时间,直接input到命令行中,因为这些文件都不大于160KB,而有些文件却明显更小。 这是我input的内容,当我尝试运行文件时(HW是正确的目录)

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

我已经在这两天了,所以任何input将不胜感激! 谢谢!!

出于安全原因,shell将不会搜索当前目录(默认情况下)可执行文件。 你必须是具体的,并告诉bash你的脚本在当前目录( . )中:

 $ ./MigrateNshell.sh 

如Marc B指出的,将第一行更改为以下内容

 #!/bin/bash 

然后将脚本标记为可执行文件并从命令行执行

 chmod +x MigrateNshell.sh ./MigrateNshell.sh 

或者简单地通过传递脚本的命令行来执行bash作为参数

 /bin/bash MigrateNshell.sh 

确保你没有使用“PATH”作为变量,这将覆盖环境变量的现有路径。

也尝试dos2unix的shell脚本,因为有时它具有Windows行结束和shell不能识别它。

 $ 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 ,我的shell将首先看看是否有一个可执行的命令/usr/local/bin/foo 。 如果有,它将执行/usr/local/bin/foo 。 如果没有,它会看到是否有一个可执行的命令/usr/bin/foo ,如果不存在,它会查看/bin/foo存在等,直到它到达/Users/david/bin/foo

如果在这些目录中找不到foo命令,它会告诉我找不到命令

有几种方法可以处理这个问题:

  • 使用命令bash foo因为foo是一个shell脚本。
  • 在执行如/Users/david/foo$PWD/foo或者只是纯粹的./foo命令时,包括目录名称。
  • 更改$PATH变量,将包含命令的目录添加到PATH。

如果.bash_profile不存在,您可以修改$HOME/.bash_profile$HOME/.profile 。 我这样做是为了添加/usr/local/bin ,我首先放在我的路径中。 这样,我可以覆盖OS中的标准命令。 例如,我有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 

现在你的脚本应该没有./

拉杰·达格拉

尝试chmod u+x MigrateNshell.sh

第一:

 chmod 777 ./MigrateNshell.sh 

然后:

 ./MigrateNshell.sh 

或者,将您的程序添加到$ PATH变量中的目录中。 示例: 路径变量示例然后允许您在没有./情况下调用程序