23

有什么方法可以将脚本标记为“作为源运行”,这样您就不必添加source或“。” 每次都命令它?即,如果我编写一个名为“sup”的脚本,我想将其称为

sup Argument

而不是

source sup Argument

或者

. sup Argument

基本上,我试图cd在脚本中使用。

4

4 回答 4

33

Bash 在它之前分叉并启动一个 subshel​​l 方式,或者你的内核甚至考虑它应该在那里做什么。这不是您可以“撤消”的事情。所以不,这是不可能的。

谢天谢地。

改为查看bash函数:

sup() {
    ...
}

把它放在你的~/.bashrc.

于 2009-04-15T17:37:22.997 回答
24

在运行 shell 时,有两种方法可以调用 shell 脚本:

  • 执行脚本会产生一个新进程,脚本正在其中运行。这是通过键入脚本名称来完成的,如果它是可执行的并且以

    #!/bin/bash
    行,或直接调用
    /bin/bash mycmd.sh

  • 获取脚本在其父外壳(即您正在输入命令的外壳)内运行它。这是通过键入

    source mycmd.sh
    或者
    . mycmd.sh

因此,没有来源的 shell 脚本中的 cd永远不会传播到其父 shell,因为这会违反进程隔离。

如果您只对cd感兴趣,则可以使用 cd "shortcuts" 摆脱脚本...查看 bash doc,位于 CDPATH env var。

否则,您可以使用别名来键入单个命令,而不是 source 或 .:

alias mycmd="source mycmd.sh"
于 2009-04-15T16:31:35.120 回答
10

为其创建别名:

alias sup=". ~/bin/sup"

或者沿着这些路线。

另请参阅:为什么 cd 在 bash shell 脚本中不起作用?


通过反例回答评论:在 Solaris 10 上进行 Korn Shell 实验表明我可以做到:

$ pwd
/work1/jleffler
$ echo "cd /work5/atria" > $HOME/bin/yyy
$ alias yyy=". ~/bin/yyy"
$ yyy
$ pwd
/work5/atria
$

在 Solaris 10 上对 Bash (3.00.16) 进行的实验也显示了相同的行为。


于 2009-04-15T16:26:07.770 回答
7

如果在调用时对脚本进行子外壳,则无法在当前环境中获取脚本。

但是,您可以检查脚本是否有来源,如果没有,则强制脚本终止:

if [ -z "$PS1" ] ; then
    echo "This script must be sourced. Use \"source <script>\" instead."
    exit
fi

同样,您可以强制脚本不作为来源,而是改为子外壳(保留当前的外壳环境):

if [ "$PS1" ] ; then
    echo "This script cannot be sourced. Use \"./<script>\" instead."
    return
fi

这两个版本都可以作为要点:请参阅请来源不要来源

于 2016-03-24T10:41:49.913 回答