bash Shell 脚本未运行,未找到命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16529658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:42:29  来源:igfitidea点击:

Shell script not running, command not found

bashshellunixscripting

提问by ChickadeeChick

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.

这一系列的 grep 只是将每个位点的每个位点的 DNA 序列数据提取到新的文本文件中。Samples...txt 文件具有站点的样品 ID 号,.fasta 文件具有按样品 ID 组织的序列信息;如果我单独运行它,grepping 在命令行中工作得很好。

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 结尾。回波线是有关计数的数据(每个位点的碱基对、分析中的种群、每个位点的样本等),程序需要这些信息。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.shand chmod u+x FILENAME.shto 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 (LF) 和编码:Unicode (UTF-8)) 在与脚本中使用的所有文件相同的目录中。我尝试使用chmod +x FILENAME.shchmod u+x FILENAME.sh尝试确保它是可执行的,但无济于事。即使我将脚本缩减为一个 grep 行(带有 #!/bin/bash 第一行),我也无法让它工作。当我直接在命令行中键入它时,这个过程只需要一点时间,因为这些文件都没有大于 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!!

我已经陷入这个僵局两天了,所以任何输入都将不胜感激!谢谢!!

回答by chepner

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

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

$ ./MigrateNshell.sh

回答by Ryan Williams

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

回答by janhavi

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

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

回答by Adolfo

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

也尝试dos2unix使用 shell 脚本,因为有时它有 Windows 行结尾并且 shell 无法识别它。

$ dos2unix MigrateNshell.sh

This helps sometimes.

这有时会有所帮助。

回答by Aminah Nuraini

Try chmod u+x MigrateNshell.sh

尝试 chmod u+x MigrateNshell.sh

回答by David W.

Unix has a variable called PATHthat 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 fooat 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/fooand if not there, it will look to see if /bin/fooexists, 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 fooin any of those directories, it tell me command not found.

如果foo在这些目录中的任何一个目录中都找不到命令,它会告诉我command not found

There are several ways I can handle this issue:

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

  • Use the commandbash foosince foois a shell script.
  • Include the directory name when you eecute the command like /Users/david/fooor $PWD/fooor just plain ./foo.
  • Change your $PATHvariable to add the directory that contains your commands to the PATH.
  • 使用该命令,bash foo因为它foo是一个 shell 脚本。
  • 当您执行像/Users/david/fooor$PWD/foo或只是 plain 之类的命令时,请包括目录名称./foo
  • 更改您的$PATH变量以将包含您的命令的目录添加到 PATH。

You can modify $HOME/.bash_profileor $HOME/.profileif .bash_profiledoesn't exist. I did that to add in /usr/local/binwhich 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 antcommand in /usr/local/bin, so my version of antwill execute first. I also added $HOME/binto 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/.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 中来执行它。

回答by broadmonkey

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

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

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

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

回答by Marc B

#! /bin/bash
  ^---

remove the indicated space. The shebang should be

删除指定的空格。该shebang应该是

#!/bin/bash

回答by Raj Dagla

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

拉吉·达格拉

回答by James Gawron

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 指定了一个无效的位置,你就会遇到问题。