shell 设置环境变量的问题

2017-03-24 12:57:01 +08:00
 lancegin

遇到一个不能理解的问题

在 shell 脚本中设置环境变量,执行脚本之后环境变量未生效,但在 terminal 手动 source 一下 bashrc 之后就生效了

部分 shell 脚本如下:

#!/bin/bash
.
.
.
DS_KEYFROM="xxx"
DS_KEY="xxx"
echo "export DS_KEYFROM=\"$DS_KEYFROM\"" >> ~/.bashrc
echo "export DS_KEY=\"$DS_KEY\"" >> ~/.bashrc
source ~/.bashrc
.
.
.

执行脚本之后echo $DS_KEYFROMecho $DS_KEY都没有值

但是查看 bashrc cat ~/.bashrc是显示已经设置成功的:

.
.
.
export DS_KEYFROM="xxx"
export DS_KEY="xxx"
.
.
.

此时如果手动 source 一下 bashrc source ~/.bashrc,环境变量就生效了。

有人知道怎么解决这个问题吗?如何直接执行脚本之后就让环境变量生效?

7293 次点击
所在节点    程序员
30 条回复
Dx2619
2017-03-24 13:01:11 +08:00
因为脚本执行的 shell 进程号和执行完脚步 echo 的进程号不一致呀。
Dx2619
2017-03-24 13:04:13 +08:00
@Dx2619 因为脚本执行的 shell 进程号和你在脚本使用过后 echo 时用的 shell 的进程号不一致。你在当前 shell 手工 source 一下或者开一个新的 shell 就可以了
Dx2619
2017-03-24 13:09:34 +08:00
简单说是因为当前 shell 未重载 bashrc 导致的。可以试试. ./a.sh
lancegin
2017-03-24 13:11:26 +08:00
@Dx2619
但现在我的需求就是在不手动 source 的前提下直接让环境变量生效,如体直接在 shell 脚本里面的 `source ~/.bashrc`

ps 重开一个 shell 也是无效的 没有手动 source 的前提下 感觉就是没有设置成功的
lancegin
2017-03-24 13:15:08 +08:00
@Dx2619 刚觉像是直接执行脚本的时候 开了一个子 shell ,于是我脚本中的 source 命令相当于在子 shell 中执行了
imkh
2017-03-24 13:25:08 +08:00
用 source script.sh 直接执行脚本 不用 sh script.sh
greyterry
2017-03-24 13:27:38 +08:00
1 楼正解
lancegin
2017-03-24 13:34:14 +08:00
@imkh 如果这是个 install 脚本 有没有办法可以直接通过 raw 执行呢? 还是我必须得把脚本下载到本地之后再手动 source 执行?
imkh
2017-03-24 13:36:55 +08:00
@lancegin 一样的。 source script.sh 就是. ./script.sh ,在当前 shell 内执行、 而不是产生一个 sub-shell 来执行
skydiver
2017-03-24 13:46:12 +08:00
@lancegin eval $(curl xxxx)
lancegin
2017-03-24 13:51:58 +08:00
@imkh 了解 目前确实只有手动 source 才能解决问题了
thekll
2017-03-24 15:35:03 +08:00
感觉你好像并没理解楼上两位的意思。
https://en.m.wikipedia.org/wiki/Source_(command)
thekll
2017-03-24 15:36:39 +08:00
直接 source 执行你的脚本。
lancegin
2017-03-24 15:48:50 +08:00
@thekll 楼上说的都明白 只是没有解决我的问题 。我是希望不通过手动 source 执行就能解决问题,然而貌似并不行。

具体情况是这样
假设有一段 install 脚本放在 github 仓库上,那我可以用 `curl -s raw_file.sh | bash` 直接执行,但如果脚本里面有设置环境变量的语句,那就无法实现了
artandlol
2017-03-24 16:00:22 +08:00
要嘛是写死在
/etc/rc.local 然后 reboot
或者写在 /etc/profile 然后 source /etc/profile
要嘛只能在程序内部调用

不建议放在 bashrc ,因为定时任务的时候是没有登陆操作,没法加载你这个 bashrc
lancegin
2017-03-24 16:22:43 +08:00
@artandlol 就是个在当前用户下作用的小脚本,所以就放 bashrc 了👨🏼‍💻
julyclyde
2017-03-24 16:28:19 +08:00
@artandlol rc.local 也不是全局的
21grams
2017-03-24 16:29:38 +08:00
所以你以为 source 是做什么用的
lancegin
2017-03-24 16:30:38 +08:00
@21grams 天真的以为在脚本中 source 就足够了
thekll
2017-03-24 22:16:28 +08:00
Bash 有好几种启动方式: login 、 interactive 等,相关的几个配置文件作用也有区别。

~/.bashrc 好像对于 Bash 脚本文件是不起作用的。
你可以试试~/.bash_profile 、~/.profile 。

具体说明请参考:
https://en.m.wikipedia.org/wiki/Bash_(Unix_shell)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/350007

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX