前言: bash不同于其他的语言。它和unix命令紧密结合。所以,精通bash的过程,就是精通unix命令的过程。
1. && 与 ;
test -e . && echo "Yes"
解释:&& 和 ";" 的区别是,如果前一个命令不成功,则后面的命令不能执行。而 ";" 不论前面的命令是否执行,后面的命令一定执行。也就是说,";" 和 "||" 功能相同。例如, ls asdfd ; echo "Yes" 和 ls asdfd || echo "Yes" 相同。
2. linux下的true和false命令
解释:再shell下,居然还有true和false这样的命令。一般在/bin 下。直接返回编程语言中的True和False值,其他什么都不做。厉害吧!
3. for 循环
for fn in *; doecho "$fn"done
解释:"*"在命令行下指代一个目录下的所有文件(包括子目录)。在shell脚本里,指代当前目录下的所有文件和子文件夹(和python比较相似)。当然,这里也可以使用列表,列表值之间用一个空格隔开,例如 for fn in tom dick harry; do。
4. echo "fsadfad" 自动加载\n
解释: 不论再命令行还是在shell脚本下,echo 在没有加选项的情况下都自动加载一个换行符(\n)。所以,echo "" 就相当于输入了一个换行符。若要取消换行符,则需要加上 -n。例如, echo -n "dfasdfasdf"。同时,echo也不会直接解释换行符,如 echo "fasdf\ndfasdf"。如果要echo能分析特殊字符(注意这里是特殊字符),需要使用 ”-e“。如,echo -e "fasdfsdf\n\t\basdf"。
5. ls -1
ls -1
解释: 这里的“1”不是“l”。 增加这个选项的目的是,在每个文件后面用换行符代替ls输出文件之间的空格符。使每一行只有一个文件名。
6. 用户输入表达式和PS提示符
PS3="Choose (1-5):"
echo "Choose from the list below."
select name in red green blue yellow magenta
dobreak
done
echo "You chose $name."
解释:PS3是为select提供提示符。而PS1则是shell命令行前面的提示符。如 [username@fedora path]$。PS2是未完成表达式时候,出现的提示符,例如,使用 “ 没有结尾引号时候,SHELL会在下一行出现一个>的提示符。
7. date
date +%N
解释:date [option] ...[+format]。这里+%N是format,而且所有format前面都要加上”+“。
8. touch
touch filename
解释:常常用touch生成一个新的文件名。使用过多以至于以为touch就是用于生成新的文件的。其实不是,touch命令是用来修改文件的访问和修改时间到当前时间的,所以如果文件已经存在,则touch不会覆盖原有文件,而只是修改文件的时间到当前时间而已。
9. 获取子字符串
string="this is a substring test"
substring=${string:10:9}
解释:substring=${string_variable_name:starting_position:length}
。
10. 字符串替换
alpha="This is a test string in which the word \"test\" is replaced."
beta="${alpha/test/replace}"
beta="${alpha//test/replace}"
解释:用"replace"替换”test“。如果想替换字符串里所有的”test“,就使用 第三行的表达式。
11. 列表和数组
array=(red green blue yellow magenta)
len=${#array[*]}
echo "The array has $len members. They are:"
i=0
while [ $i -lt $len ]; doecho "$i: ${array[$i]}"let i++
done
list="cricket frog cat dog"
poem="I wanna be a x\n\
A x is what I'd love to be\n\
If I became a x\n\
How happy I would be.\n"
for critter in $list; doecho -e ${poem//x/$critter}
done
解释:在bash脚本里,array和list的赋值是有区别的。详见代码。
12. bash自带的正则表达式
x='123-22-3432'
if [[ $x =~ [0-9]{3}-[0-9]{2}-[0-9]{4} ]]
thenecho "right"
elseecho "Wrong"
fi
$ echo {a..z}
for n in {0..5}
doecho $n
done
解释:自bash version3之后,bash可以使用正则表达式了。注意空格,赋值没有空格,比较运算式左右两边都需要有空格。正则表达式需要用”[[“。而且不能使用perl中的正则表达式\w、\d和\s。
13. ~/.bash_history
解释:这个文件是存放前次登录shell(bash)之后执行的命令。而当前执行的命令被被保存在记忆体中,直到退出shell以后,才会保存到.bash_history里。默认是1000条。
14. alias
alias lm='ls -la'
解释:alias命令设定别名。但是只在当前的bash下。关闭当前bash后,别名就会消失。
15. type
type cd
type ll
type -t ll
type -a ll
解释:type命令是查看命令是否是bash内置命令或者外部命令,或者是否是别名。
16. 变量和路径的关系。
解释:在脚本里,最好在开头把所有路径都写到变量里。这样,如果路径发生变化后,不需要长篇地修改脚本里的路径地址。
17. 赋值、取值、重置和输出
myname=John
myname=John\ \'s\ brother
myname="John 's brother"
myname="$name"yes
myname=${name}yes
PATH=$PATH:/home/asdfd/bin
PATH="$PATH":/home/asdfd/bin
PATH=${PATH}:/home/asdfd/bin
echo $myname
export myname
unset myname
解释:在命令行下,所付的值不需要引号,除非含有空格和不能使用在命令行的特殊字符(或者用跳脱元字)。在脚本里也同样。所有变量都用 echo 取值,用unset清空变量。在 echo 后的变量需要加 $,在unset和export之后的变量不用 $。
18. 输出内核的版本号
cd /lib/modules/`uname -r`/kernel
解释:反单引号内的 uname -r 输出当前所使用内核的版本号。这是一个非常实用的命令。会在多处使用到。
19. $(commands) 和 `commands`
version=`uname -r`
version=$(uname -r)
解释:这两个表达都是一样的。但是后者比较容易区分。建议使用后者。但是,$( ) 和 ${ } 是完全不同的。不能混淆了。前者内嵌命令,后者内嵌变量。
20. 在linux下搜索文档。find、ls、locate
ls -R /usr/share | grep -i firefox.png
find /usr/share -iname firefox.png
locate firefox.png
解释:使用第一个,还需要grep做辅助查找。使用第二个则比较明朗,而且find也可以使用基础正则表达式。locate功能非常强大,也同样可以使用基础正则表达式。locate -r。
21. linux环境变量。查看命令用env、export、set。
解释:比较奥常见的环境变量有HOME、PATH、SHELL、HISTSIZE、MAIL、LANG、RANDOM、UID、USER、USERNAME、PWD、HOSTNAME、SSH_AUTH_SOCK、HOSTTYPE、OSTYPE、MACHTYPE。系统内定的变量(不论是否为环境变量)都需要大写。
22. PS1
解释:
\d :可顯示出『星期 月 日』的日期格式,如:"Mon Feb 2"
\H :完整的主機名稱。舉例來說,鳥哥的練習機為『www.vbird.tsai』
\h :僅取主機名稱在第一個小數點之前的名字,如鳥哥主機則為『www』後面省略
\t :顯示時間,為 24 小時格式的『HH:MM:SS』
\T :顯示時間,為 12 小時格式的『HH:MM:SS』
\A :顯示時間,為 24 小時格式的『HH:MM』
\@ :顯示時間,為 12 小時格式的『am/pm』樣式
\u :目前使用者的帳號名稱,如『root』;
\v :BASH 的版本資訊,如鳥哥的測試主機版本為 3.2.25(1),僅取『3.2』顯示
\w :完整的工作目錄名稱,由根目錄寫起的目錄名稱。但家目錄會以 ~ 取代;
\W :利用 basename 函數取得工作目錄名稱,所以僅會列出最後一個目錄名。
\# :下達的第幾個指令。
\$ :提示字元,如果是 root 時,提示字元為 # ,否則就是 $ 囉~
23. 父程序与子程序,自定义变量和环境变量。export 可以把自定义变量编程环境变量让子程序也可以使用。
username=John
export username
export
解释:子程序能继承父程序的环境变量,但是不能继承父程序的自定义变量。所以需要export声明一下,设定好后,使用export 查看。export 后面的变量不需要加 $符号。
资料:
1. http://www.arachnoid.com/linux/shell_programming.html
2. http://linux.vbird.org/linux_basic/0320bash.php#bash
3. http://www.panix.com/~elflord/unix/bash-tute.html
4. http://www.hypexr.org/bash_tutorial.php