我试图编写一个shell脚本,当运行时,将设置一些环境变量,这些变量将在调用者的shell中保持设置。

setenv FOO foo

在csh/tcsh中,或

export FOO=foo

在sh/bash中只在脚本执行期间设置它。

我已经知道了

source myscript

将运行脚本的命令,而不是启动一个新的shell,这可能导致设置“调用者的”环境。

但问题是:

我希望这个脚本可以从bash或csh中调用。换句话说,我希望任何一个shell的用户都能够运行我的脚本,并更改他们的shell环境。因此,'source'对我来说不适用,因为运行csh的用户不能获取bash脚本的源代码,而运行bash的用户也不能获取csh脚本的源代码。

有没有合理的解决方案,不需要在脚本上编写和维护两个版本?


当前回答

您可以使用不同的bash_profile调用另一个Bash。 此外,您还可以创建特殊的bash_profile用于多bashprofile环境。

请记住,您可以在bashprofile中使用函数,并且该函数将全局可用。 例如,“function user {export USER_NAME $1}”可以在运行时设置变量,例如:user olegchir && env | grep olegchir

其他回答

这不是我所说的杰出的,但如果您需要从shell调用脚本,这也可以工作。这不是一个很好的解决方案,但对于一个单一的静态环境变量,它工作得足够好了。

1)。创建一个条件为0(成功)或1(不成功)的脚本

if [[ $foo == "True" ]]; then
    exit 0
else
    exit 1

2)。创建依赖于退出代码的别名。

alias='myscript.sh && export MyVariable'

调用别名,别名调用脚本,脚本计算条件,条件必须通过'&&'退出0,以便在父shell中设置环境变量。

这是垃圾,但在紧要关头可以派上用场。

使用“点空格脚本”调用语法。例如,下面是如何使用脚本的完整路径:

. /path/to/set_env_vars.sh

如果你和脚本在同一个目录中,下面是如何做到这一点:

. set_env_vars.sh

它们在当前shell下执行脚本,而不是加载另一个脚本(如果您执行./set_env_vars.sh,就会发生这种情况)。因为它在同一个shell中运行,所以当它退出时,您设置的环境变量将可用。

这与调用源set_env_vars.sh是一样的事情,但它的输入更短,并且可能在源不能工作的某些地方工作。

简短的回答是否定的,您不能更改父进程的环境,但似乎您想要的是一个具有自定义环境变量和用户选择的shell的环境。

所以为什么不简单地

#!/usr/bin/env bash
FOO=foo $SHELL

然后,当您完成环境时,只需退出。

在我的.bash_profile我有:

# No Proxy
function noproxy
{
    /usr/local/sbin/noproxy  #turn off proxy server
    unset http_proxy HTTP_PROXY https_proxy HTTPs_PROXY
}


# Proxy
function setproxy
{
    sh /usr/local/sbin/proxyon  #turn on proxy server 
    http_proxy=http://127.0.0.1:8118/
    HTTP_PROXY=$http_proxy
    https_proxy=$http_proxy
    HTTPS_PROXY=$https_proxy
    export http_proxy https_proxy HTTP_PROXY HTTPS_PROXY
}

当我想禁用代理时, 函数在登录shell中运行并设置变量 正如预期和希望的那样。

我创建了一个解决方案使用管道,eval和信号。

parent() {
    if [ -z "$G_EVAL_FD" ]; then
            die 1 "Rode primeiro parent_setup no processo pai"
    fi
    if [ $(ppid) = "$$" ]; then
            "$@"
    else
            kill -SIGUSR1 $$
            echo "$@">&$G_EVAL_FD
    fi
}
parent_setup() {
    G_EVAL_FD=99
    tempfile=$(mktemp -u)
    mkfifo "$tempfile"
    eval "exec $G_EVAL_FD<>'$tempfile'"
    rm -f "$tempfile"
    trap "read CMD <&$G_EVAL_FD; eval \"\$CMD\"" USR1
}
parent_setup #on parent shell context
( A=1 ); echo $A # prints nothing
( parent A=1 ); echo $A # prints 1

它可能适用于任何命令。