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

时间:2021-01-07 23:57:15

I am very, very new to UNIX programming (running on MacOSX Mountain Lion via Terminal). I've been learning the basics from a bioinformatics and molecular methods course (we've had two classes) where we will eventually be using perl and python for data management purposes. Anyway, we have been tasked with writing a shell script to take data from a group of files and write it to a new file in a format that can be read by a specific program (Migrate-N).

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

I have gotten a number of functions to do exactly what I need independently when I type them into the command line, but when I put them all together in a script and try to run it I get an error. Here are the details (I apologize for the length):

当我在命令行中输入它们时,我已经得到了许多函数来独立完成我需要的工作,但是当我把它们放在一个脚本中并试图运行它时,我得到了一个错误。以下是一些细节(我为长度表示歉意):

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

The series of greps are just pulling out DNA sequence data for each site for each locus into new text files. The Samples...txt files have the sample ID numbers for a site, the .fasta files have the sequence information organized by sample ID; the grepping works just fine in command line if I run it individually.

greps系列只是将每个位点的DNA序列数据提取到新的文本文件中。样品…txt文件具有站点的样例ID号,.fasta文件具有按样例ID组织的序列信息;如果我单独运行的话,在命令行中,这个启动就可以正常工作了。

The second group of code creates the actual new file I need to end up with, that ends in .mig. The echo lines are data about counts (basepairs per locus, populations in the analysis, samples per site, etc.) that the program needs information on. The cat lines are to mash together the locus by site data created by all the grepping below the site-specific information dictated in the echo line. You no doubt get the picture.

第二组代码创建了我需要结束的实际新文件,以.mig结尾。回波线是程序需要信息的计数(每个位点的basepairs、分析中的种群、每个站点的样本等)的数据。cat行将根据响应线中指定的站点特定信息下面的所有grepping创建的站点数据合并到一起。你一定明白了。

For creating the shell script I've been starting in Excel so I can easily copy-paste/autofill cells, saving as tab-delimited text, then opening that text file in TextWrangler to remove the tabs before saving as a .sh file (Line breaks: Unix (LF) and Encoding: Unicode (UTF-8)) in the same directory as all the files used in the script. I've tried using chmod +x FILENAME.sh and chmod u+x FILENAME.sh to try to make sure it is executable, but to no avail. Even if I cut the script down to just a single grep line (with the #! /bin/bash first line) I can't get it to work. The process only takes a moment when I type it directly into the command line as none of these files are larger than 160KB and some are significantly smaller. This is what I type in and what I get when I try to run the file (HW is the correct directory)

创建shell脚本我已经开始在Excel中,所以我可以很容易地复制粘贴/自动填充细胞,保存为文本一样,然后在TextWrangler打开文本文件保存为. sh文件之前删除标签(换行符:Unix(低频)和编码:Unicode(utf - 8))在相同的目录中所有的文件中使用的脚本。我试过使用chmod +x文件名。sh和chmod u+x文件名。sh试图确保它是可执行的,但没有用。即使我将脚本缩减为一个grep行(使用#!/bin/bash第一行)我不能让它工作。当我直接将它输入到命令行时,这个过程只需要花一点时间,因为这些文件中没有一个大于160KB,而有些则明显小于160KB。这是我输入的内容,当我尝试运行文件时得到的内容(HW是正确的目录)

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

I've been at this impass for two days now, so any input would be greatly appreciated! Thanks!!

我已经在这里呆了两天了,所以非常感谢您的帮助!谢谢! !

11 个解决方案

#1


28  

For security reasons, the shell will not search the current directory (by default) for an executable. You have to be specific, and tell bash that your script is in the current directory (.):

出于安全原因,shell将不会(默认情况下)搜索当前目录以获得可执行文件。您必须是特定的,并告诉bash您的脚本位于当前目录(.):

$ ./MigrateNshell.sh

#2


15  

Change the first line to the following as pointed out by Marc B

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

#!/bin/bash 

Then mark the script as executable and execute it from the command line

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

chmod +x MigrateNshell.sh
./MigrateNshell.sh

or simply execute bash from the command line passing in your script as a parameter

或者简单地从命令行执行bash作为参数。

/bin/bash MigrateNshell.sh

#3


9  

Make sure you are not using "PATH" as a variable, which will override the existing PATH for environment variables.

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

#4


7  

Also try to dos2unix the shell script, because sometimes it has Windows line endings and the shell does not recognize it.

还可以尝试使用shell脚本dos2unix,因为有时它有Windows行结尾,而shell不识别它。

$ dos2unix MigrateNshell.sh

This helps sometimes.

有时这可以帮助。

#5


2  

There have been a few good comments about adding the shebang line to the beginning of the script. I'd like to add a recommendation to use the env command as well, for additional portability.

关于在脚本的开头添加shebang行,有一些很好的评论。我还想添加一个建议来使用env命令,以获得额外的可移植性。

While #!/bin/bash may be the correct location on your system, that's not universal. Additionally, that may not be the user's preferred bash. #!/usr/bin/env bash will select the first bash found in the path.

虽然# !/bin/bash可能是您系统上的正确位置,这不是通用的。此外,这可能不是用户首选的bash。# !/usr/bin/env bash将选择路径中找到的第一个bash。

#6


2  

Try chmod u+x MigrateNshell.sh

chmod u + x MigrateNshell.sh试试

#7


1  

#! /bin/bash
  ^---

remove the indicated space. The shebang should be

删除指定的空间。工作应该

#!/bin/bash

#8


1  

Unix has a variable called PATH that is a list of directories where to find commands.

Unix有一个名为PATH的变量,它是查找命令的目录列表。

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

If I type a command foo at the command line, my shell will first see if there's an executable command /usr/local/bin/foo. If there is, it will execute /usr/local/bin/foo. If not, it will see if there's an executable command /usr/bin/foo and if not there, it will look to see if /bin/foo exists, etc. until it gets to /Users/david/bin/foo.

如果我在命令行输入命令foo,我的shell将首先看到是否有可执行的命令/usr/ local/bin/foo。如果有,它将执行/usr/ local/bin/foo。如果没有,它将查看是否有可执行命令/usr/bin/foo,如果没有,它将查看/bin/foo是否存在,等等,直到它到达/Users/david/bin/foo。

If it can't find a command foo in any of those directories, it tell me command not found.

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

There are several ways I can handle this issue:

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

  • Use the commandbash foo since foo is a shell script.
  • 使用commandbash foo,因为foo是shell脚本。
  • Include the directory name when you eecute the command like /Users/david/foo or $PWD/foo or just plain ./foo.
  • 当您删除/Users/david/foo或$PWD/foo或只是普通的./foo时,包含目录名。
  • Change your $PATH variable to add the directory that contains your commands to the PATH.
  • 更改$PATH变量,将包含命令的目录添加到路径中。

You can modify $HOME/.bash_profile or $HOME/.profile if .bash_profile doesn't exist. I did that to add in /usr/local/bin which I placed first in my path. This way, I can override the standard commands that are in the OS. For example, I have Ant 1.9.1, but the Mac came with Ant 1.8.4. I put my ant command in /usr/local/bin, so my version of antwill execute first. I also added $HOME/bin to the end of the PATH for my own commands. If I had a file like the one you want to execute, I'll place it in $HOME/bin to execute it.

您可以修改$ HOME /。bash_profile或$ HOME /。如果.bash_profile不存在,则配置文件。我这样做是为了添加/usr/local/bin,这是我在路径中首先放置的。这样,我就可以重写操作系统中的标准命令。例如,我有Ant 1.9.1,但是Mac有Ant 1.8.4。我将ant命令放在/usr/local/bin中,因此我的antwill首先执行。我还为我自己的命令在路径的末尾添加了$HOME/bin。如果我有一个类似您想要执行的文件,我将把它放在$HOME/bin中执行。

#9


0  

Also make sure /bin/bash is the proper location for bash .... if you took that line from an example somewhere it may not match your particular server. If you are specifying an invalid location for bash you're going to have a problem.

也确保/bin/bash bash ....的适当位置如果您从某个示例中提取这一行,它可能与您的特定服务器不匹配。如果您正在为bash指定一个无效的位置,那么您将会遇到问题。

#10


0  

Add below lines in your .profile path

在.profile路径中添加以下行。

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

export PATH

Now your script should work without ./

现在你的脚本应该可以不用了

Raj Dagla

Raj Dagla

#11


-3  

First:

第一:

chmod 777 ./MigrateNshell.sh

Then:

然后:

./MigrateNshell.sh

Or, add your program to a directory recognized in your $PATH variable. Example: Path Variable Example Which will then allow you to call your program without ./

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

#1


28  

For security reasons, the shell will not search the current directory (by default) for an executable. You have to be specific, and tell bash that your script is in the current directory (.):

出于安全原因,shell将不会(默认情况下)搜索当前目录以获得可执行文件。您必须是特定的,并告诉bash您的脚本位于当前目录(.):

$ ./MigrateNshell.sh

#2


15  

Change the first line to the following as pointed out by Marc B

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

#!/bin/bash 

Then mark the script as executable and execute it from the command line

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

chmod +x MigrateNshell.sh
./MigrateNshell.sh

or simply execute bash from the command line passing in your script as a parameter

或者简单地从命令行执行bash作为参数。

/bin/bash MigrateNshell.sh

#3


9  

Make sure you are not using "PATH" as a variable, which will override the existing PATH for environment variables.

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

#4


7  

Also try to dos2unix the shell script, because sometimes it has Windows line endings and the shell does not recognize it.

还可以尝试使用shell脚本dos2unix,因为有时它有Windows行结尾,而shell不识别它。

$ dos2unix MigrateNshell.sh

This helps sometimes.

有时这可以帮助。

#5


2  

There have been a few good comments about adding the shebang line to the beginning of the script. I'd like to add a recommendation to use the env command as well, for additional portability.

关于在脚本的开头添加shebang行,有一些很好的评论。我还想添加一个建议来使用env命令,以获得额外的可移植性。

While #!/bin/bash may be the correct location on your system, that's not universal. Additionally, that may not be the user's preferred bash. #!/usr/bin/env bash will select the first bash found in the path.

虽然# !/bin/bash可能是您系统上的正确位置,这不是通用的。此外,这可能不是用户首选的bash。# !/usr/bin/env bash将选择路径中找到的第一个bash。

#6


2  

Try chmod u+x MigrateNshell.sh

chmod u + x MigrateNshell.sh试试

#7


1  

#! /bin/bash
  ^---

remove the indicated space. The shebang should be

删除指定的空间。工作应该

#!/bin/bash

#8


1  

Unix has a variable called PATH that is a list of directories where to find commands.

Unix有一个名为PATH的变量,它是查找命令的目录列表。

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

If I type a command foo at the command line, my shell will first see if there's an executable command /usr/local/bin/foo. If there is, it will execute /usr/local/bin/foo. If not, it will see if there's an executable command /usr/bin/foo and if not there, it will look to see if /bin/foo exists, etc. until it gets to /Users/david/bin/foo.

如果我在命令行输入命令foo,我的shell将首先看到是否有可执行的命令/usr/ local/bin/foo。如果有,它将执行/usr/ local/bin/foo。如果没有,它将查看是否有可执行命令/usr/bin/foo,如果没有,它将查看/bin/foo是否存在,等等,直到它到达/Users/david/bin/foo。

If it can't find a command foo in any of those directories, it tell me command not found.

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

There are several ways I can handle this issue:

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

  • Use the commandbash foo since foo is a shell script.
  • 使用commandbash foo,因为foo是shell脚本。
  • Include the directory name when you eecute the command like /Users/david/foo or $PWD/foo or just plain ./foo.
  • 当您删除/Users/david/foo或$PWD/foo或只是普通的./foo时,包含目录名。
  • Change your $PATH variable to add the directory that contains your commands to the PATH.
  • 更改$PATH变量,将包含命令的目录添加到路径中。

You can modify $HOME/.bash_profile or $HOME/.profile if .bash_profile doesn't exist. I did that to add in /usr/local/bin which I placed first in my path. This way, I can override the standard commands that are in the OS. For example, I have Ant 1.9.1, but the Mac came with Ant 1.8.4. I put my ant command in /usr/local/bin, so my version of antwill execute first. I also added $HOME/bin to the end of the PATH for my own commands. If I had a file like the one you want to execute, I'll place it in $HOME/bin to execute it.

您可以修改$ HOME /。bash_profile或$ HOME /。如果.bash_profile不存在,则配置文件。我这样做是为了添加/usr/local/bin,这是我在路径中首先放置的。这样,我就可以重写操作系统中的标准命令。例如,我有Ant 1.9.1,但是Mac有Ant 1.8.4。我将ant命令放在/usr/local/bin中,因此我的antwill首先执行。我还为我自己的命令在路径的末尾添加了$HOME/bin。如果我有一个类似您想要执行的文件,我将把它放在$HOME/bin中执行。

#9


0  

Also make sure /bin/bash is the proper location for bash .... if you took that line from an example somewhere it may not match your particular server. If you are specifying an invalid location for bash you're going to have a problem.

也确保/bin/bash bash ....的适当位置如果您从某个示例中提取这一行,它可能与您的特定服务器不匹配。如果您正在为bash指定一个无效的位置,那么您将会遇到问题。

#10


0  

Add below lines in your .profile path

在.profile路径中添加以下行。

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

export PATH

Now your script should work without ./

现在你的脚本应该可以不用了

Raj Dagla

Raj Dagla

#11


-3  

First:

第一:

chmod 777 ./MigrateNshell.sh

Then:

然后:

./MigrateNshell.sh

Or, add your program to a directory recognized in your $PATH variable. Example: Path Variable Example Which will then allow you to call your program without ./

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