Shell脚本设置环境变量

130

我希望编写一个shell脚本来导出变量。

下面是我列出的脚本:

echo "Perform Operation in su mode"
export ARCH=arm
echo "Export ARCH=arm Executed"
export PATH='/home/linux/Practise/linux-devkit/bin/:$PATH';
echo "Export path done"
export CROSS_COMPILE='/home/linux/Practise/linux-devkit/bin/arm-arago-linux-gnueabi-';
echo "Export CROSS_COMPILE done"

但是这似乎无法正常工作。我需要在shell提示符下逐个执行命令。


你使用的是哪个 shell(例如 bash、ksh、sh)? - Tom
可能是Save Global variables BASH的重复问题。 - tripleee
2
可能是从bash脚本将变量导出到环境而不使用源的重复问题。 - user513951
5个回答

320

您需要将脚本作为source或快捷方式.来运行。

source ./myscript.sh
. ./myscript.sh

这将在现有的 shell 中运行,确保脚本创建或修改的任何变量会在脚本完成后可用。

仅使用文件名来运行脚本将在单独的子 shell 中执行脚本。


2
通过使用 source ./setenv.sh -: 会出现源未找到的错误。而使用 . ./setenv.sh 则会提示无法打开 setenv.sh。请问能否帮我解决这个问题。谢谢。 - Vishal
3
我为了那些该死的导出变量(zsh)而苦思冥想了一个小时,尝试了typeset -gx,export等等,当时感到非常困惑。然而,我不知道子Shell会在其自己的范围内执行。感谢你拯救了我免受愤怒管理的威胁,让我度过了这个难关。 - Inoperable
有没有一种方法可以使用继承变量运行脚本,但不允许它修改外部 shell 中的变量? - Gunar Gessner

61
请展示脚本的更多部分,并告诉我们您需要逐个执行的命令并想要简化它们。 同时,您必须使用双引号而不是单引号来扩展变量。
export PATH="/home/linux/Practise/linux-devkit/bin/:$PATH"

单个命令结尾的分号也是不必要的。

到目前为止:

#!/bin/sh
echo "Perform Operation in su mode"
export ARCH=arm
echo "Export ARCH=arm Executed"
export PATH="/home/linux/Practise/linux-devkit/bin/:$PATH"
echo "Export path done"
export CROSS_COMPILE='/home/linux/Practise/linux-devkit/bin/arm-arago-linux-gnueabi-' ## What's next to -?
echo "Export CROSS_COMPILE done"
# continue your compilation commands here
...

您可以使用以下命令运行su

su -c 'sh /path/to/script.sh'

注意:原帖子并没有明确要求在交互式shell中使用shell脚本创建导出变量的步骤。他只是要求评估他的脚本最多。他没有提及关于如何使用他的脚本的详细信息。它可以通过使用交互式shell中的“.”或“source”来实现。它可以是一个独立的脚本,也可以是从另一个脚本“source”的。环境变量不特定于交互式shell。这个答案解决了他的问题。


1
你好,konsolebox!非常感谢你。但我不理解这两者之间的区别:双引号中的 export PATH="/home/linux/Practise/linux-devkit/bin/:$PATH" 和单引号中的 export CROSS_COMPILE='/home/linux/Practise/linux-devkit/bin/arm-arago-linux-gnueabi-'。你修改的脚本运行良好。 - Prag Rao
@PragRao 参数扩展在单引号中不会发生。您可以在此处进一步了解引用的详细信息[https://www.gnu.org/software/bash/manual/html_node/Quoting.html]。 - konsolebox
3
@konsolebox的问题标题听起来像是“用Shell脚本设置环境变量”,社区中大部分人发现这个问题只是为了解决从当前shell(source.)运行此类脚本的问题。我很感激你确切地回答了OP的问题,但我是通过谷歌发现了这个主题,并且下一个答案比你的回答更有帮助。第二个答案(使用source.)得到了点赞,证实了我的观点... - avtomaton
@avtomaton,这不是关于其他人在谷歌上找到它的问题。这只涉及到问题的原始方法。如果您对问题应该如何更改或答案应该如何呈现有疑虑,请考虑在元中讨论。 - konsolebox

6

以 source= 参数运行脚本以启动调试模式。

source= ./myscript.sh

0
在我的情况下,我在=前后都加了额外的空格。例如,在我的shell文件(比如deploy.sh)中,
我最初写的是:
GIT_SHA = $(git rev-parse HEAD)

但我通过使用以下方法解决了这个问题:

GIT_SHA=$(git rev-parse HEAD)

请注意,在=之前和之后不应该有任何空格。

0

我无法使用source ./myscript.sh解决它。它显示源文件未找到的错误。
当使用. ./myscript.sh时也失败了。它会提示无法打开myscript.sh。

所以我的选择是将它放在一个文本文件中,在下一个脚本中调用。

#!/bin/sh
echo "Perform Operation in su mode"
echo "ARCH=arm" >> environment.txt
echo "Export ARCH=arm Executed"
export PATH="/home/linux/Practise/linux-devkit/bin/:$PATH"
echo "Export path done"
export "CROSS_COMPILE='/home/linux/Practise/linux-devkit/bin/arm-arago-linux-gnueabi-' ## What's next to -?" >> environment.txt
echo "Export CROSS_COMPILE done"
# continue your compilation commands here
...

然后在需要的时候调用它:

while read -r line; do
    line=$(sed -e 's/[[:space:]]*$//' <<<${line})
    var=`echo $line | cut -d '=' -f1`; test=$(echo $var)
    if [ -z "$(test)" ];then eval export "$line";fi
done <environment.txt

1
你可以修改 myscript.sh,使其生成一个名为 environment.sh 的文件(带有导出语句),然后只需在需要时使用 source environment.sh 而不是 while 循环。 - slajma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接