问题描述
我写了一个简单的脚本。当我运行sh <myscriptname.sh>
时,我得到了正确的输出,但是当我运行./<myscriptname.sh>
时,我收到了一个错误。
我在做sh
和./
时有什么区别?
最佳解决办法
通过将文件名传递给脚本解释程序来运行任何脚本时,您将运行解释程序,并将脚本作为传递给它的参数。例如,这看起来像’sh’过程,其参数为’filename.sh’。 sh
解释器正在打开该文件。
另一方面,如果您自己运行脚本,系统会调用指定的解释程序并输入脚本内容。在这种情况下,该过程看起来像没有参数的’filename.sh’。
你应该确保你有一个爆炸线:
#!/bin/bash
# bash script here
bang line是脚本中的第一行,以相同的两个字符#!
开头,这些是系统在尝试执行脚本时读取的内容,然后系统立即将脚本传递给程序。请注意,这一行与bash无关,对python和perl也同样适用,即使它们是非常不同的语言。您可以使用#!/usr/bin/python
作为示例,然后使用python代码进行操作。
获得脚本后,请确保已设置执行权限:
chmod a+x filename.sh
然后,您可以将脚本作为自己的进程运行:
./filename.sh
或者将文件放入具有良好程序名称的已知位置,例如/usr/sbin
,并从任何地方运行:
sudo cp filename.sh /usr/sbin/program-name
program-name
这实际上是使用具有正确权限的爆炸线的实际好处 – 这都是关于部署的。如果用户必须记住运行脚本的程序,那么很难让用户运行脚本。请记住每次要运行脚本时都要提供完整的脚本路径。例如,将它放在/usr/local/bin
中,并使其可执行,可以为试图使用您的脚本的人节省大量的悲伤。然后,这些程序可供计算机上的所有用户使用。
这也有利于识别。如果你进入top
程序,没有bang行的脚本将只有解释器的名称,即bash
,perl
或python
。但是,如果使用正确的权限运行脚本,则会显示脚本的名称。
注意:如果要分发每个人都可以访问的脚本,请创建一个手册页和一个deb软件包来安装它。我们需要减少在线随机脚本的数量,并增加可以卸载的deb数量。
次佳解决办法
简短版本:
-
sh
是命令行解释器(破折号)。运行sh my_script
使破折号解释脚本。 -
./
尝试通过查看第一行来找出要使用的解释器。例如。#!/bin/bash
,甚至是#!/bin/ruby
(与运行ruby my_script
相反)。
第三种解决办法
你做的不同是,
-
使用
sh
,您运行的程序将解释脚本中的行,就像您在终端的交互式提示符上键入它们一样, -
使用
./
,您可以创建一个快捷方式,假设脚本就在您所在的当前目录中,并且它将是可执行的(因为例如您发布了chmod +x myscript.sh
),为您节省了宝贵的未来时间:-)
第四种办法
您可能会收到错误的主要原因有三个:
-
该文件不可执行运行
chmod +x <myscriptname.sh>
来修复它 -
分区不允许运行脚本(已安装“
noexec
”)将脚本复制到/usr/local/bin
-
#!
线有错误,确保第一行是#!/bin/sh
或#!/bin/bash
如果您的第一行看起来正确,但仍然无法正常工作,请确保该文件没有DOS行结尾。
错误看起来像这样:
$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory
您可以通过运行dos2unix <myscriptname.sh>
来修复它,或者如果没有它,可以通过perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>
来修复它。