在没有源命令的情况下将 bash 脚本作为源运行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/752525/
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 18:06:13  来源:igfitidea点击:

Run bash script as source without source command

bash

提问by typeoneerror

Is there any way to mark a script to be "run as source" so you don't have to add the sourceor "." command to it every time? i.e., if I write a script called "sup", I'd like to call it as

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

sup Argument

rather than

而不是

source sup Argument

or

或者

. sup Argument

Basically, I'm trying to use cdwithin a script.

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

回答by lhunath

Bash forks and starts a subshell way before it or your kernel even considers what it's supposed to do in there. It's not something you can "undo". So no, it's impossible.

Bash 在它或您的内核甚至考虑它应该在那里做什么之前派生并启动一个子shell。这不是您可以“撤消”的。所以不,这是不可能的。

Thankfully.

谢天谢地。

Look into bashfunctions instead:

bash改为查看函数:

sup() {
    ...
}

Put that in your ~/.bashrc.

把它放在你的~/.bashrc.

回答by Varkhan

When you are running a shell, there are two ways to invoke a shell script:

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

  • Executinga script spawns a new process inside which the script is running. This is done by typing the script name, if it is made executable and starts with a

    #!/bin/bash
    line, or directly invoking
    /bin/bash mycmd.sh

  • Sourcinga script runs it inside its parent shell (i.e. the one you are typing commands into). This is done by typing

    source mycmd.sh
    or
    . mycmd.sh

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

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

  • Sourcing脚本在其父 shell 中运行它(即您正在输入命令的那个)。这是通过键入

    source mycmd.sh
    或者
    . mycmd.sh

So the cd inside a shell script that isn't sourced is nevergoing to propagate to its parent shell, as this would violate process isolation.

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

If the cdis all you are interested about, you can get rid of the script by using cd "shortcuts"... Take a look into the bash doc, at the CDPATH env var.

如果您只对cd感兴趣,则可以使用 cd "shortcuts" 来删除脚本...查看 CDPATH env var 中的 bash 文档。

Otherwise, you can use an alias to be able to type a single command, instead of source or .:

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

alias mycmd="source mycmd.sh"

回答by Jonathan Leffler

Create an alias for it:

为其创建别名:

alias sup=". ~/bin/sup"

Or along those lines.

或者沿着这些路线。

See also: Why doesn't cd work in a bash shell script?

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



Answering comment by counter-example: experimentation with Korn Shell on Solaris 10 shows that I can do:

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

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

Experimentation with Bash (3.00.16) on Solaris 10 also shows the same behaviour.

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



回答by Tim

It is not possible to source a script in your current environment if you sub-shell the script at invoke.

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

However, you can check that script is sourcedand force the script to terminate if not:

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

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

The same way, you can force a script not to be sourcedbut to be sub-shelled instead (preserve current shell environment):

以同样的方式,您可以强制脚本不获取源,而是使用子外壳(保留当前外壳环境):

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

Both versions are available as gists: see please sourceand don't source.

两个版本都可以作为要点提供:请参阅 sourcedon't source