为什么Ubuntu不支持sh example.sh
命令?
在某些情况下cd $wd; ./example.sh
它比更方便。add PATH
login.sh
:
~/bin/logmitgw.sh -i 4564646 dfdsfsdf
logmitgw.sh
:
some code
当我跑步的时候sh ~/bin/login.sh
我得到:
sh: 0: Can't open ~/bin/login.sh
ls -l ~/bin/login.sh
输出-rwxrwxr-x
答案1
Ubuntu 确实支持运行sh example.sh
。如果你其他一切都做对了,它就可以正常工作。你的情况是似乎是您给出了错误的脚本路径。
当你在 Ubuntu 中打开终端时,它很可能会启动一个 Bash shell。我假设你的情况就是这样。
此外,该命令sh
还会调用不同的 shell:
$ command -v sh
/usr/bin/sh
$ ls -l /usr/bin/sh
lrwxrwxrwx 1 root root 13 Aug 4 11:43 /usr/bin/sh -> /usr/bin/dash
也就是说,/usr/bin/sh
是指向短跑shell。在某些系统上,sh
符号链接可能指向另一个 shell。
sh
可能出错的一件事是系统中没有。
以下是示例脚本:
$ echo 'echo "works!"' > ~/bin/example.sh
$ sh ~/bin/example.sh
works!
如果我删除sh
符号链接,我会收到错误:
$ sudo rm /usr/bin/sh
$ sh ~/bin/example.sh
bash: /usr/bin/sh: No such file or directory
请注意,这不是您遇到的错误。
我跑去sudo ln -s /usr/bin/dash /usr/bin/sh
再次建立符号链接并回来sh
。
另一个问题可能是该文件不是 shell 脚本,dash 无法运行它,或者它是一个 shell 脚本,但与 dash 不兼容。在这种情况下,您将收到某种语法错误,例如:
$ file /bin/bash
/bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a6cb40078351e05121d46daa768e271846d5cc54, for GNU/Linux 3.2.0, stripped
$ sh /bin/bash
/bin/bash: 1: ELF: not found
/bin/bash: 2: Syntax error: Unterminated quoted string
$ file /usr/bin/uname
/usr/bin/uname: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3354931bca4ff072b26258a956ffde08ead5f341, for GNU/Linux 3.2.0, stripped
$ sh /usr/bin/uname
/usr/bin/uname: 1: Syntax error: word unexpected (expecting ")")
但您没有收到这样的错误。
当要求 dash shell 运行不存在的文件时,它会输出您在问题中显示的错误:
$ ls ~/bin/anything
ls: cannot access '/home/zanna/bin/anything': No such file or directory
$ sh ~/bin/anything
sh: 0: Can't open /home/zanna/bin/anything
此错误中的0
是当前文件:
$ echo 'echo $0' > ~/bin/something
$ sh ~/bin/something
/home/zanna/bin/something
在你的问题中,你说你跑了
sh ~/bin/login.sh
并得到
sh: 0: Can't open ~/bin/login.sh
但该错误毫无意义,因为波浪号~
应该扩展为主目录的路径。记住我的错误:
$ sh ~/bin/anything
sh: 0: Can't open /home/zanna/bin/anything
^___^------expansion of ~
我可以通过引用路径来重现您的错误:
$ sh ~/bin/example.sh
works!
$ sh "~/bin/example.sh"
sh: 0: Can't open ~/bin/example.sh
也许这就是你所做的。
或者,看看您的帖子的修改历史,看来你可能已经跑了
sh /bin/login.sh
这样做是行不通的,除非顶层目录中sh: 0: Can't open /bin/login.sh
有文件,否则将输出。如果您创建了这样的文件,您可能会知道,因为您必须以 root 身份执行此操作。login.sh
/bin
出现错误的另一个原因sh: 0: Can't open /path/to/file
是,您运行了sh ~/bin/login.sh
,但没有这样的文件。但是,在这种情况下,仍然会展开。此外,您给出文件~
输出的第一部分,以显示权限:ls -l
-rwxrwxr-x
因此,显然,~/bin/login.sh
这是一个具有权限 775 的常规文件。所以也许这不是问题。
请注意,当您调用解释器(例如 (da)sh)来运行脚本时,该脚本不需要具有执行权限:
$ ls -l ~/bin/example.sh
-rw-rw-r-- 1 zanna zanna 14 Aug 4 11:36 /home/zanna/bin/example.sh
$ sh ~/bin/example.sh
works!
但是你的脚本调用了另一个脚本,而没有调用解释器来运行它。如果第二个脚本没有执行权限,则会导致权限错误:
$ echo '~/bin/example.sh' > ~/bin/something
$ sh ~/bin/something
/home/zanna/bin/something: 1: /home/zanna/bin/example.sh: Permission denied
但是,再说一次,这不是您遇到的错误。
您已接受fabricator4 的答案,指出~/bin
如果存在的话,它会被添加到 PATH 中(您可以在 中看到执行此操作的代码~/.profile
),因此如果您在 中有一个可执行文件~/bin
,则可以在不指定解释器的情况下运行它,但为了使其正常工作,该文件必须具有执行权限:
$ example.sh
bash: /home/zanna/bin/example.sh: Permission denied
$ chmod u+x ~/bin/example.sh
$ example.sh
works!
(这里虽然当前 shell(我们假设是 Bash,可能不是 dash)在没有任何解释器指令)
由于该答案对您有用,因此该文件似乎存在,具有执行权限,并且是与 Bash 兼容的脚本。 那么,您尝试使用语法运行它sh example.sh
时出错的原因似乎是您引用了路径并阻止了波浪号扩展,或者完全省略了路径~
,因此,在这两种情况下,都指定了错误的文件路径。
答案2
如果脚本位于 ~/bin 中,则 ~/bin 已位于路径中。只要它是 bash 脚本,您就可以从任何地方执行它。无需 shell、无需 cd,也不需要在路径中添加任何内容。
例如:
login.sh