shell 设置环境变量的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
lancegin
V2EX    程序员

shell 设置环境变量的问题

  •  
      lancegin
    lancegin 2017-03-24 12:57:01 +08:00 7681 次点击
    这是一个创建于 3124 天前的主题,其中的信息可能已经有所发展或是发生改变。

    遇到一个不能理解的问题

    在 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,环境变量就生效了。

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

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

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

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

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

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

    具体说明请参考:
    https://en.m.ikipedia.org/wiki/Bash_(Unix_shell)
    zzlyzq
        21
    zzlyzq  
       2017-03-24 23:04:25 +08:00
    子进程无法影响到父进程的环境变量
    zzlyzq
        22
    zzlyzq  
       2017-03-24 23:04:48 +08:00
    父进程可以通过 export xx=xx 影响子进程的环境变量
    thekll
        23
    thekll  
       2017-03-25 03:56:17 +08:00
    @lancegin 我上一条回复中间一句有问题,请忽略。(不经常用,有些概念就模糊了。)
    julyclyde
        24
    julyclyde  
       2017-03-25 08:41:06 +08:00
    @zzlyzq 错。是通过 export 为尚未启动的子进程准备初始环境变量
    lancegin
        25
    lancegin  
    OP
       2017-03-25 11:51:51 +08:00
    @julyclyde 请问下,如果在用户下的 bashrc 中 export 了环境变量,那重开一个 shell 的时候为什么也无效? login 的时候不是应该要加载一次 bashrc 的吗
    shalk
        26
    shalk  
       2017-03-25 12:34:21 +08:00
    @lancegin 参考 pyenv rvm 等 一些包管理工具的做法;

    curl url | bash -

    之后,修改了 bashrc , 或者提示你 把一些内容加到 bashrc 里,但是当前 shell 不会生效。

    所以需要,重开窗口,或者 exec $SHELL -l
    lancegin
        27
    lancegin  
    OP
       2017-03-25 12:49:31 +08:00
    @shalk 嗯 我现在将脚本中的 source 语句删掉了 执行脚本完之后抛出一个 source bashrc 的提醒
    julyclyde
        28
    julyclyde  
       2017-03-25 13:17:04 +08:00
    @lancegin 你“重开”的那个 shell 是怎么开的? man bash 看 INVOCATION 那一段核对一下具体是哪一种
    lancegin
        29
    lancegin  
    OP
       2017-03-26 01:19:15 +08:00 via iPhone
    @julyclyde 后来发现是 zsh 导致,默认加载了 zshrc ,我在 zshrc 里面 source 了 bashrc 就没问题了
    julyclyde
        30
    julyclyde  
       2017-03-26 21:28:30 +08:00
    @lancegin 不错,总算是找到原因并解决了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1577 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 16:15 PVG 00:15 LAX 09:15 JFK 12:15
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86