export,sorce

本文介绍了在Linux shell中如何使用export命令将变量变为环境变量,并详细解释了变量在不同shell之间的传递方式及其生存周期。

shell与export命令

用户登录到Linux系统后,系统将启动一个用户shell。在这个shell中,可以使用shell命令或声明变量,也可以创建并运行 shell脚本程序。运行shell脚本程序时,系统将创建一个子shell。此时,系统中将有两个shell,一个是登录时系统启动的shell,另一 个是系统为运行脚本程序创建的shell。当一个脚本程序运行完毕,它的脚本shell将终止,可以返回到执行该脚本之前的shell。从这种意义上来 说,用户可以有许多 shell,每个shell都是由某个shell(称为父shell)派生的。
在子 shell中定义的变量只在该子shell内有效。如果在一个shell脚本程序中定义了一个变量,当该脚本程序运行时,这个定义的变量只是该脚本程序内 的一个局部变量,其他的shell不能引用它,要使某个变量的值可以在其他shell中被改变,可以使用export命令对已定义的变量进行输出。 export命令将使系统在创建每一个新的shell时定义这个变量的一个拷贝。这个过程称之为变量输出。
[例]在本例中,变量myfile是在dispfile脚本程序中定义的。然后用export命令将变量myfile输出至任何子shell,例如当执行printfile脚本程序时产生的子shell。 printfile脚本程序时产生的子shell。

Python代码
dispfile脚本程序清单:   
  1. /**************begin dispfile**************/   
  2. myfile=”List”   
  3. export myfile   
  4. echo “Displaying $myfile”   
  5. pr –t –n $myfile   
  6. printfile   
  7. /**************end dispfile***************/   
  8.     
  9. printfile脚本程序清单:   
  10. /**************begin printfile**************/   
  11. echo “Printing $myfile”   
  12. lpr $myfile&   
  13. /**************end printfile**************/   
  14. $dispfile   
  15. Displaying List   
  16. 1 screen   
  17. 2 modem   
  18. 3 paper   
  19. Printing List   
  20. $  
[python]  view plain  copy
  1. dispfile脚本程序清单:  
  2. /**************begin dispfile**************/  
  3. myfile=”List”  
  4. export myfile  
  5. echo “Displaying $myfile”  
  6. pr –t –n $myfile  
  7. printfile  
  8. /**************end dispfile***************/  
  9.    
  10. printfile脚本程序清单:  
  11. /**************begin printfile**************/  
  12. echo “Printing $myfile”  
  13. lpr $myfile&  
  14. /**************end printfile**************/  
  15. $dispfile  
  16. Displaying List  
  17. 1 screen  
  18. 2 modem  
  19. 3 paper  
  20. Printing List  
  21. $  
 

Linux 指令:系统设置--export

功能说明:设置或显示环境变量。

语  法:export [-fnp][变量名称]=[变量设置值]

补充说明:在shell中执行程序时,shell会提供一组环境变量。export可新增,修改或删除环境变量,供后续执行的程序使用。export的效力仅及于该此登陆操作。

参  数:
 -f  代表[变量名称]中为函数名称。 
 -n  删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执行环境中。 
 -p  列出所有的shell赋予程序的环境变量。

从学习export命令理解到的Shell环境和变量生存期


  我自己也是一个菜鸟,接触linux没有多久,最近在学习BASH的export命令时碰到了一个难道(书上说export是将自定义变量变成系统环 境变量):我在一个脚本文件中定义一个了变量,然后export变量,按照我自己的想法,执行完这个脚本后,在提示符下一定可以用echo显示出它的值, 可结果却不是这样,脚本执行完后用set根本看不到有这个变量存在。为什么呢?我百思不得其解,最后将问题贴出来,一位前辈告诉我说用source+脚本 文件就可以了,我试了一下果然可以,但一个新的问题又出来了。我将脚本中export命令删除后,用source一样可以。那这个export好像没有什 么用呀。

  在经过多次尝试后发现了一些东西,是我自己猜的,如果有什么不对的地方,请指正,谢谢。

  执行一个脚本 时,会先开启一个子shell环境(不知道执行其它程序是不是这样),然后将父shell中的所有系统环境变量复制过来,这个脚本中的语句就在子 shell中执行。(也就是说父shell的环境变量在子shell中可以调用,但反过来就不行,如果在子shell中定义了环境变量,只对该shell 或者它的子shell有效,当该子shell结束时,也可以理解为脚本执行完时,变量消失。)为了证明这一点,请看脚本内容:

  test='value'

  export test

  这样的脚本执行完后,test实际上是不存在的。接着看下面的:

  test='value'

  export test

  bash

  这里在脚本最后一行再开一个子shell,该shell应该是脚本文件所在shell的子shell,这个脚本执行完后,是可以看到test这个变量的,因为现在是处于它的子shell中,当用exit退出子shell后,test变量消失。

  如果用source对脚本进行执行时,如果不加export,就不会在子shell中看到这个变量,因为它还不是一个系统环境变量呀,如脚本内容是:

  test='value'

   用source执行后,在shell下是能看到这个变量,但再执行bash开一个子shell时,test是不会被复制到子shell中的,因为执行脚 本文件其实也是在一个子shell中运行,所以我再建另一个脚本文件执行时,是不会输入任何东西的,内容如:echo $test。所以这点特别注意了,明明在提示符下可以用echo $test输出变量值,为什么把它放进脚本文件就不行了呢?

  所以得 出的结论是:1、执行脚本时是在一个子shell环境运行的,脚本执行完后该子shell自动退出;2、一个shell中的系统环境变量才会被复制到子 shell中(用export定义的变量);3、一个shell中的系统环境变量只对该shell或者它的子shell有效,该shell结束时变量消失 (并不能返回到父shell中)。3、不用export定义的变量只对该shell有效,对子shell也是无效的。

  后来根据版主的 提示,整理了一下贴子:为什么一个脚本直接执行和用source执行不一行呢?这也是我自己碰到的一个问题。manual原文是这样的:Read and execute commands from filename in the current shell environment and return the exit status of the last command executed from filename.明白了为什么不一样了吧?直接执行一个脚本文件是在一个子shell中运行的,而source则是在当前shell环境中运行的。根据 前面的内容,你也已经明白其中的道理了吧。
不改变内容添加高亮 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { margin: 0; padding: 0; } .right { width: 400px; height: 100%; position: fixed; right: 0; top: 0; background-color: rgba(0, 0, 0, 0.1); } .right>.head>div { float: left; width: 50%; text-align: center; height: 40px; line-height: 40px; background-color: #389fc3; color: white; } .right>.head>.time { background-color: white; color: red; } .right>.head, .right>.title, .right>.content { width: 280px; border: 1px solid #ccc; } .right>.title>span { font-size: 12px; display: inline-block; width: 50%; text-align: center; height: 40px; line-height: 40px; } .right>.title>span:first-child { font-size: 14px; font-weight: 500; } .right>.content { list-style: none; margin: 0; padding: 0 0 0 5px; width: 275px; } .right>.content>li { width: 30px; height: 30px; border: 1px solid #ccc; float: left; font-size: 12px; text-align: center; line-height: 30px; margin: 5px; } .right>.content>li>a { display: block; width: 100%; height: 100%; text-decoration: none; color: black; } .right>.content>li.active { background-color: #5d9cec; color: white; } .bottom { width: 900px; position: fixed; height: 40px; bottom: 0; right: 400px; line-height: 40px; padding-left: 20px; background-color: rgba(0, 0, 0, 0.1); } .bottom>.time { color: red; } .bottom>.submit { width: 100px; height: 100%; float: right; background-color: #389fc3; color: white; text-align: center; cursor: pointer; } .clear::after { content: ""; display: block; clear: both; height: 0; overflow: hidden; opacity: 0; } .main { margin-top: 10px; border: 1px solid #ccc; width: 900px; position: relative; left: 110px; } .main-title { height: 40px; line-height: 40px; } .main-title>span:first-child { padding: 0 20px; } .main-title>.main-sorce { display: inline-block; color: white; font-size: 12px; background-color: #389fc3; border-radius: 20px; padding: 0 10px; } .main>.main-question { list-style: none; margin: 0; padding: 0; } .main>.main-question>li { padding: 20px 0; } .main>.main-question .left { float: left; width: 50px; } .main>.main-question .left>span { width: 30px; height: 30px; background-color: #5d9cec; display: inline-block; border-radius: 30px; text-align: center; color: white; line-height: 30px; margin-left: 10px; } .main>.main-question .question { float: left; padding-left: 30px; width: 80%; } .main>.main-question .question>.line { width: 100%; border-top: 0.5px solid #000; } .main>.main-question .question>ul { list-style: none; margin: 0; padding: 0; } .main>.main-question .question>ul>li { padding: 5px; } .main>.main-question .question>ul>li:hover { background-color: #eee; } .mask { width: 100%; height: 100%; position: fixed; background-color: rgba(0, 0, 0, 0.4); z-index: 999; left: 0; top: 0; display: none; } .mask>.score-panel { width: 50%; height: 50%; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; background-color: white; } </style> </head> <body> <div class="main"> <div class="main-title"> <span>单选题</span> <span class="main-sorce">共0题,合计0分</span> </div> <ul class="main-question"></ul> </div> <div class="right"> <div class="head clear"> <div>答题卡</div> <div class="time">00:00:00</div> </div> <div class="title"><span>单选题</span><span class="num">共0道</span></div> <ul class="content clear"></ul> </div> <div class="bottom clear"> <span class="time">00:00:00</span> <div class="submit">提交</div> </div> <div class="mask"> <div class="score-panel"></div> </div> <script type="module"> import getTime from "../js/time.js"; import questionList from "../js/data.js"; // 定义全局变量 var times, num, score, content, mainQuestion, submit, mask; var answerList = {}; // 存储用户答案的对象 {题目索引: 答案} // 初始化应用 init(); // 初始化函数 function init() { // 获取所有计时器元素 times = document.querySelectorAll(".time"); // 为每个计时器设置120秒倒计时 times.forEach((item) => getTime(120, item)); // 设置分数显示 setScore(); // 设置右侧题目导航 setRightContent(); // 创建题目内容 createQuestion(); // 绑定提交事件 submitAnswer(); } // 设置分数信息 function setScore() { // 获取题目数量和分数显示元素 num = document.querySelector(".num"); score = document.querySelector(".main-sorce"); // 显示总题数 num.innerHTML = `共${questionList.length}题`; // 计算总分 var s = questionList.reduce((value, item) => value + item.score, 0); // 显示总分信息 score.innerHTML = `共${questionList.length}题,合计${s}分`; } // 创建右侧题目导航 function setRightContent() { // 获取导航容器 content = document.querySelector(".content"); // 生成题目导航链接 content.innerHTML = questionList .map((item, index) => { // 为每个题目创建带锚点的链接 return `<li><a href='#${index}'>${index + 1}</a></li>`; }) .join(""); } // 创建题目内容 function createQuestion() { // 获取题目容器 mainQuestion = document.querySelector(".main-question"); // 绑定题目点击事件委托 mainQuestion.addEventListener("click", questionHandler); // 生成所有题目HTML mainQuestion.innerHTML = questionList .map((item, index) => { return ` <li class="clear" id='${index}'> <div class="left"><span>${index + 1}</span></div> <div class="question"> <div>${item.question}</div> <div class="line"></div> <ul> ${item.options .map((t, ind) => { // 生成选项(A/B/C/D) const optionChar = String.fromCharCode(65 + ind); return `<li> <input type="radio" name="${index}" data='${optionChar}'/> ${optionChar + "." + t} </li>`; }) .join("")} </ul> </div> </li> `; }) .join(""); } // 处理题目选择 function questionHandler(e) { // 只处理input元素的点击 if (e.target.nodeName !== "INPUT") return; const name = e.target.name; // 获取题目索引 const data = e.target.getAttribute("data"); // 获取选项值(A/B/C/D) // 存储答案 {题目索引: 选项} answerList[name] = data; } // 提交功能初始化 function submitAnswer() { // 获取提交按钮和遮罩层 submit = document.querySelector(".submit"); mask = document.querySelector(".mask"); // 绑定提交事件 submit.addEventListener("click", clickHandler); // 绑定遮罩层点击事件 mask.addEventListener("click", maskHiddenHandler); } // 提交按钮点击处理 function clickHandler(e) { // 显示分数面板 mask.style.display = "block"; // 计算得分 const totalScore = Object.keys(answerList).reduce((value, key) => { const questionIndex = Number(key); // 答案正确时累加分数 if (questionList[questionIndex].result === answerList[key]) { value += questionList[questionIndex].score; } return value; }, 0); // 显示得分 document.querySelector(".score-panel").innerHTML = `您一共得了${totalScore}分`; } // 关闭分数面板 function maskHiddenHandler(e) { mask.style.display = "none"; } </script> </body> </html>
最新发布
08-02
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值