# 練習 5:Bash:環境變量,`env`,`set`,`export`
> 原文:[Exercise 5. Bash: environment variables, env, set, export](https://archive.fo/M8Ndm)
> 譯者:[飛龍](https://github.com/wizardforcel)
> 協議:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
> 自豪地采用[谷歌翻譯](https://translate.google.cn/)
請考慮以下內容:你希望程序打印出你的用戶名。這個程序怎么知道的?在 Linux 中有一些環境變量。這意味著你的 shell 中有許多變量,其中許多變量自動設置,每次運行程序時,其中一些變量將傳遞給該程序。
詳細說明:
+ 一些變量只為你當前的 shell 設置。它們被稱為本地 shell 變量。你可以通過鍵入`set`,一個 bash 內置命令來列出它們 ,這意味著沒有啟動其它程序,之后你執行了它。此命令由 bash 本身處理。
+ 其他變量被傳遞到你從當前 shell 啟動的每個程序。它們被稱為環境變量,可以通過`env`程序列出,這意味著,通過鍵入`env`, 你將看到,你啟動的每個程序獲得了什么變量。
你可能想要深入挖掘。要做到這一點,掌握 [subshell](http://en.wikipedia.org/wiki/Child_process) 的概念,這是一個子進程,當你運行程序時創建,并且成為你的程序。
現在,你將學習如何創建變量以及如何使用變量。
## 這樣做
```
1: foo='Hello World!'
2: echo $foo
3: set | grep foo
4: env | grep foo
5: export foo
6: env | grep foo
7: foo='ls -al'
8: $foo
```
## 你會看到什么
```
uset1@vm1:~$ foo='Hello World!'
user1@vm1:~$ echo $foo
Hello World!
user1@vm1:~$ set | grep foo
foo='Hello World!'
user1@vm1:~$ env | grep foo
user1@vm1:~$ export foo
user1@vm1:~$ env | grep foo
foo=Hello World!
user1@vm1:~$ foo='ls -al'
user1@vm1:~$ $foo
total 36
drwxr-xr-x 2 user1 user1 4096 Jun 14 12:23 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw------- 1 user1 user1 4042 Jun 15 18:52 .bash_history
-rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout
-rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc
-rw------- 1 user1 user1 50 Jun 15 18:41 .lesshst
-rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile
-rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak
-rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1
```
## 解釋
1. 創建變量`foo` ,并將`Hello World!`這一行放在其中。
2. 打印出變量`foo`。
3. 打印所有環境變量的列表,它傳遞給`grep`,打印出只包含變量`foo`的行。注意變量`foo`存在。
4. 打印所有環境變量列表,它們傳遞給你執行的任何程序。注意變量`foo`不存在。
5. 使變量`foo`可用于從當前 shell 執行的所有程序。
6. 現在你可以看到,你的變量確實可用于你執行的所有程序。
7. 將`ls /`放入變量`foo`。
8. 執行包含在變量`foo`中的命令。
## 附加題
+ 輸入并執行`env`和`set`。看看有多少個不同的變量?不用擔心,通常你可以通過谷歌搜索,快速了解一個變量的作用。嘗試這樣做。
+ 嘗試輸入:
```
set | egrep '^[[:alpha:]].*$'
```
現在,試試`set`。看見我在這里做了什么嘛?快速的解釋是:
```
egrep '^[[:alpha:]].*$'
```
僅僅打印出以字母開頭的行,它是每個字母,并忽略其他行。現在不要糾結這個,也不要糾結`|`符號。以后我會解釋它。
+ 在這里閱讀`env`和`set`之間的區別:<http://stackoverflow.com/questions/3341372/differnce-between-the-shell-and-environment-variable-in-bash>。記住,stackoverflow 是你的朋友!我會重復多次。
+ 嘗試輸入`set FOO=helloworld bash -c 'echo $FOO'`。這里是解釋:<http://stackoverflow.com/questions/10938483/bash-specifying-environment-variables-for-echo-on-command-line>。同樣,不要太糾結,你會在大量練習之后再次碰到它,我保證。
+ 試試這個:
```
PS1_BAK=$PS1
PS1='Hello, world! $(pwd) > '
PS1=$PS1_BAK
```
注意我使用`$(pwd)`,將命令輸出作為變量訪問。現在,鍵入`man bash /PS1`(是的,只是斜杠),按下`<ENTER>`。你現在可以按下`n`查看下一個結果。瀏覽 PROMPTING,并鍵入`q`來退出`man`。現在,訪問 <http://stackexchange.com/> 并搜索`bash PS1`。了解這兩個文檔來源的區別。
- 笨辦法學 Linux 中文版
- 練習 0:起步
- 練習 1:文本編輯器,vim
- 練習 2:文本瀏覽器,少即是多
- 練習 3:Bash:Shell、.profile、.bashrc、.bash_history
- 練習 4:Bash:處理文件,pwd,ls,cp,mv,rm,touch
- 練習 5:Bash:環境變量,env,set,export
- 練習 6:Bash:語言設置,LANG,locale,dpkg-reconfigure locales
- 練習 7:Bash:重定向,stdin,stdout,stderr,<,>,>>,|,tee,pv
- 練習 8:更多的重定向和過濾:head,tail,awk,grep,sed
- 練習 9:Bash:任務控制,jobs,fg
- 練習 10:Bash:程序退出代碼(返回狀態)
- 練習 11:總結
- 練習 12:文檔:man,info
- 練習 13:文檔:Google
- 練習 14:包管理:Debian 包管理工具aptitude
- 練習 15:系統啟動:運行級別,/etc/init.d,rcconf,update-rc.d
- 練習 16:處理進程,ps,kill
- 練習 17:任務調度:cron,at
- 練習 18:日志:/var/log,rsyslog,logger
- 練習 19:文件系統:掛載,mount,/etc/fstab
- 練習 20:文件系統:修改和創建文件系統,tune2fs,mkfs
- 練習 21:文件系統:修改根目錄,chroot
- 練習 22:文件系統:移動數據,tar,dd
- 練習 23:文件系統:權限,chown,chmod,umask
- 練習 24:接口配置,ifconfig,netstat,iproute2,ss,route
- 練習 25:網絡:配置文件,/etc/network/interfaces
- 練習 26:網絡:封包過濾配置,iptables
- 練習 27:安全 Shell,ssh,sshd,scp
- 練習 28:性能:獲取性能情況,uptime,free,top
- 練習 29:內核:內核消息,dmesg
- 練習 30:打磨、洗練、重復:總復習
- 下一步做什么
- Debian 手動安裝