将bash脚本作为源而不使用源命令运行

时间:2021-11-13 22:12:01

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

有没有办法将脚本标记为“作为源运行”,因此您不必添加源或“。”每次命令它?也就是说,如果我写一个名为“sup”的脚本,我想称之为

sup Argument

rather than

source sup Argument

or

. sup Argument

Basically, I'm trying to use cd within a script.

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

4 个解决方案

#1


Bash forks and stars 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在它或你的内核甚至考虑它应该在那里做什么之前分叉和星星。这不是你可以“撤消”的东西。所以不,这是不可能的。

Thankfully.

Look into bash functions instead:

相反,请查看bash函数:

sup() {
    ...
}

Put that in your ~/.bashrc.

把它放在〜/ .bashrc中。

#2


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

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

  • Executing a 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

    执行脚本会生成一个运行脚本的新进程。这是通过键入脚本名称来完成的,如果它是可执行的并以a开头

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

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

    获取脚本在其父shell(即您正在键入命令的那个)中运行它。这是通过键入来完成的

    source mycmd.sh
    or
    . mycmd.sh

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

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

If the cd is 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“快捷方式”删除脚本...在CDPATH环境变量中查看bash文档。

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

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

alias mycmd="source mycmd.sh"

#3


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)进行的实验也显示了相同的行为。


#4


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 sourced and force the script to terminate if not:

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

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

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

同样,您可以强制不要获取脚本,而是替换为子shell(保留当前的shell环境):

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

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

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

#1


Bash forks and stars 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在它或你的内核甚至考虑它应该在那里做什么之前分叉和星星。这不是你可以“撤消”的东西。所以不,这是不可能的。

Thankfully.

Look into bash functions instead:

相反,请查看bash函数:

sup() {
    ...
}

Put that in your ~/.bashrc.

把它放在〜/ .bashrc中。

#2


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

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

  • Executing a 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

    执行脚本会生成一个运行脚本的新进程。这是通过键入脚本名称来完成的,如果它是可执行的并以a开头

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

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

    获取脚本在其父shell(即您正在键入命令的那个)中运行它。这是通过键入来完成的

    source mycmd.sh
    or
    . mycmd.sh

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

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

If the cd is 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“快捷方式”删除脚本...在CDPATH环境变量中查看bash文档。

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

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

alias mycmd="source mycmd.sh"

#3


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)进行的实验也显示了相同的行为。


#4


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 sourced and force the script to terminate if not:

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

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

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

同样,您可以强制不要获取脚本,而是替换为子shell(保留当前的shell环境):

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

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

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