linux bash變數作用域 一,思考一個問題,當在shell里執行某個程式時,shell是怎麼找到這個程式的? shell會去$PATH環境變數定義的目錄里去找這個命令。環境變數里一般包括 這麼多目錄,這些目錄下又有上千個程式,從這麼多目錄里的,這麼多程式里查找肯定是花費時間的。shell為了提 ...
linux bash變數作用域
一,思考一個問題,當在shell里執行某個程式時,shell是怎麼找到這個程式的?
shell會去$PATH環境變數定義的目錄里去找這個命令。環境變數里一般包括/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
這麼多目錄,這些目錄下又有上千個程式,從這麼多目錄里的,這麼多程式里查找肯定是花費時間的。shell為了提高查找效率,使用了緩存機制,這個機制叫hash
。。
有了hash緩存後,shell先去hash里查找,如果找到了,就使用;如果沒有找到,才去$PATH環境變數定義的目錄里去找,找到後,把命令的路勁加程式名放入hash中。
註意:如果是shell的buildin命令,不會放入hash。
hash命令用法:
查看hash里都緩存了哪些程式:
hash
hits:代表此命令,被命中了幾次。
# hash hits command 1 /usr/bin/cat 2 /usr/bin/ls
詳細查看hash里都緩存了哪些程式:
hash -l
# hash -l builtin hash -p /usr/bin/cat cat builtin hash -p /usr/bin/ls ls
清除某個緩存:
hash -d cat
# hash -d cat # hash hits command 2 /usr/bin/ls
清除所有緩存:
hash -r
# hash -r # hash hash: hash table empty
為什麼還要清除緩存?理由:當把命令移動到別的目錄後,用原來的緩存就找不到命令了,shell會報出錯誤,所有要清除。
二,bash變數的作用域
shell進程的子孫進程。
在shell進程里又啟動了別的shell進程,下麵的例子是在bash里又啟動了一個bash,讓後在新啟動的bash里,又啟動了一個csh。
# pstree systemd─┬ ├─sshd───sshd───bash───pstree # bash # csh # pstree systemd─┬ ├sshd───sshd───bash───bash───csh───pstree
bash變數種類:
按變數的作用域範圍分為:
本地變數:作用域僅為當前shell進程
驗證本地變數的作用域:
# firstName=jerry # echo $firstName jerry # csh # echo $firstName firstName: Undefined variable. # exit exit # echo $firstName jerry
賦值:name=value
引用:${name},$name
- "":變數會被替換成其值
- '':變數不會被替換成其值
查看變數:set
撤銷變數:unset name。註意name前不要加$
# firstname=tom # echo $firstname tom # unset firstname # echo $firstname
環境變數:作用域為當前shell進程,及其子孫shell進程。
驗證環境變數的作用域:
# fn=tom # echo $fn tom # export fn # csh # echo $fn tom # exit exit # echo $fn tom
賦值:
export name=value
name=value
export name
declare -x name=value
name=value
declare -x name
引用:同本地變數。
撤銷變數:unset name。註意name前不要加$
bash內嵌的環境變數:
PATH
,HISTORY
,HISTSIZE
,HISTFILESIZE
,HISTCONTROL
,SHELL
,HOME
,UID
,PWD
,OLDPWD
查看環境變數命令:
export
,declare -x
,printenv
,env
只讀變數(常量):作用域是當前shell進程,且不可以撤銷。隨當前shell進程的終止而終止。
- declare -r name
- readonly name
檢證常量的作用域:
# la=foo # declare -r la # echo $la foo # csh # $echo la echo: Undefined variable. # exit exit # echo $la foo # la=aa -bash: la: readonly variable [root@localhost ~]# unset la -bash: unset: la: cannot unset: readonly variable
- 局部變數:函數里的變數,作用域僅為函數內。
位置參數變數:shell腳本的參數
特殊變數:
- $?:上一個命令的執行結果。0:成功;1-255:失敗。
- ...
bash里,多個命令一起執行
多個命令連續執行:
command1;command2;command3...
這些命令都會被執行。
多個命令邏輯連續執行
根據前面命令的執行結果(成功或者失敗),決定是否執行後面的命令。
前一個命令執行成功後,後面的命令才讓執行:
&&
例子:先查看目錄存不存在,存在了才進入此目錄
# pwd /root # ls /sdf && cd /tmp ls: cannot access /sdf: No such file or directory # pwd /root # ls /sdf || cd /tmp ls: cannot access /sdf: No such file or directory # pwd /tmp
前一個命令執行失敗後,後面的命令才讓執行:
||
例子:先某個用戶存不存在,不存在則創建此用戶;存在了就不創建了。
# pwd /root # ls /sdf || cd /tmp ls: cannot access /sdf: No such file or directory # pwd /tmp
三,如何執行shell腳本文件
1,用chmod
賦予shell文件可執行許可權。
./shell.sh
2,把shell文件(這個文件不需要有執行許可權)作為參數,傳給bash程式。
bash shell.sh
練習1
1,顯示/etc目錄下所有以p(不區分大小寫)開頭的文件或者目錄本身。
2,顯示/var目錄下的所有文件或目錄,並將顯示結果中的小寫字母轉換為大寫後顯示
3,創建臨時文件/tmp/myfile.XXXX
#!/bin/bash ls -ld /etc/p* ls -d /var/* | tr 'a-z' 'A-Z' mktemp /tmp/myfile.XXXX
四,bash配置文件
1,啟動shell進程的種類:
- 交互方式啟動的shell進程
- 直接通過終端輸入賬號密碼後登錄後,啟動的shell進程
- 使用su命令:
su - username
,或者使用su-l username
,登錄後,啟動的shell進程
- 非交互方式啟動的shell進程
- 使用su命令:
su username
,登錄後,啟動的shell進程 - 在gnome或者kde下打開終端後,啟動的shell進程
- 執行shell腳本文件時,啟動的shell進程
- 使用su命令:
2,bash配置文件的種類
profile類
對所有用戶都有效,只有管理員才可以修改下麵的配置文件
- /etc/profile
- /etc/profile.d/*.sh
僅對當前用戶有效
~/.bash_profile
功用:
- 用於定義環境變數
- 運行命令或腳本
bashrc類
對所有用戶都有效,只有管理員才可以修改下麵的配置文件
/etc/bashrc
僅對當前用戶有效
~/.bashrc
功用:
- 定義本地變數
- 定義命令別名
3,bash配置文件的載入順序。
交互方式啟動的shell進程
/etc/profile--->/etc/profile.d/*.sh--->~/.bash_profile--->~/.bashrc--->/etc/bashrc
非交互方式啟動的shell進程
~/.bashrc--->/etc/bashrc--->/etc/profile.d/*.sh
4,重新載入配置文件
- 當修改配置文件後,是不會立即生效的
- 使用
source 配置名
,讓修改的配置立即生效
五,用emacs編寫shell腳本
1,自動補全的快捷鍵:ESC TAB