您的位置:首页 > 运维架构 > Shell

linux shell(一)

2015-10-21 11:48 706 查看

linux shell(一)

近来在看《LINUX SHELL脚本攻略》,感觉还不错,对于入门和梳理以前知识还是挺适合的,以下是只是本人对书上内容的摘要,mark下来方便自己查看。

1. shebang

1.1 shell脚本文本一般以 #!/bin/bash 开头,使用脚本运行必须含有这一行,shell程序读取脚本的首行时,会识别/bin/bash,并在内部以如下命令行执行该脚本:

$ /bin/bash myscript.sh


另外一种执行方式是,将脚本作为sh 的命令行参数:

$ sh myscript.sh


1.2 配置文件(~/.bashrc), 历史记录文件(~/.bash_history)

2. 终端打印

2.1 echo

$ echo hello world !  #可以这样在命令行使用,但无法在所要显示的文本中使用,因为在bash shell中被用作命令定界符。
$ echo "hello world \!" #!在双引号中需要进行转义
$ echo 'hello world !' #注意bash不会对单引号中的变量(如$var)求值,而是照原样显示。


默认情况下,echo会将一个换行符追加到文本尾部。可以使用-n来忽略结尾换行符。

$ ehco -e "1\t2\t3"    #ehco -e 包含转义序列
1       2       3
$echo -e "\e[1;31m red text \e[0m"   #打印彩色文本


2.2 printf

printf "%-5s %-10s %-4s\n" NO Name Mark
printf "%-5s %-10s %-4.2f\n" 01 Tom 90.3456
printf "%-5s %-10s %-4.2f\n" 02 Jack 89.2345
printf "%-5s %-10s %-4.2f\n" 03 Jeff 98.4323


%s, %c, %d和%f都是格式替代符,其对应的参数可以置于带引号的格式字符串之后。

3. 变量与环境变量

3.1 prepare

$ pgrep vi   # 可以使用pgrep获取vi的进程ID
6325


然后通过以下命令获取与该进程相关的环境变量

$ cat /proc/6325/environ (或者cat /proc/6325/environ | tr '\0' '\n' 进行格式化输出)
HOSTNAME=localhost.localdomainTERM=vt100SHELL=/bin/bashHISTSIZE=1000SSH_CLIENT=192.168.3.200 51845 22SSH_TTY=/dev/pts/1JRE_HOME=/usr/local/java/jdk1.7.0.....


3.2 赋值与引用

var=value赋值操作(注意:var = value 是相等操作,注意区分)

+变量名或+{变量名} 进行引用变量值

$ echo $var  # or echo ${var}


设置环境变量使用export命令:

$ export PATH="$PATH:/home/user/java"
(或者
PATH="$ PATH:/home/user/java"  export PATH)


3.3 其他

3.3.1 获取字符串长度

length=${#var}


3.3.2 识别当前sh ell版本

echo $SHEEL 或 echo $0


3.3.3 判断是否超级用户

echo $UID  # root用户的UID是0


3.3.4 修改bash提示字符串(username@hostname:~$)

在文件~/.bash文件中PS1=…..

3.3.5 使用函数添加环境变量

prepend() { [ -d "$2" ] && eval $1=\"$2\$\{$1:+':'\$$1\}\" && export $1 ; }


remark:

${parameter:+expression} #如果parameter有值且不为空,则使用expression的值


4. 进行数学运算

可以利用let、(())和[]执行基本的算数操作。进行高级操作时可以使用expr和bc。普通的变量赋值方法定义数值时,会被存储为字符串,可以通过一些方法使它能像数字一样进行处理。

4.1 使用let可以直接执行基本的算数操作。

$ a=5+2
$ b=3+2
$ let result=a+b
$ echo $result


自加:leta++,自减: let b–

$ let a+=6 #(等同于a=a+6)
$ b-=6  #(等同于b=b-6)


4.2 使用[](和let类似)

result=$[ a + b + 10] 或者 result=$[ $a + $b + 10]


4.3 使用(()),变量名前需要加$;使用expr也行

result=$(( a + 50 ))
result=$(expr $a + 50)


4.4 以上只用于执行整数,如使用浮点数,可用bc,并应用一些高级函数

echo "4 * 0.56" | bc
echo "scale=1;1/6" | bc
echo "obase=2;100" | bc  # 转换成二进制
echo "obase=10;ibase=2;1100" | bc  #二进制转十进制


5. 文件描述符和重定向

5.1 系统预留的文件描述符

0 —— stdin(标准输入)

1 —— stdout(标准输出)

2 —— stdin(标准错误)

5.2 将输出文本重定向到一个文件

echo "demo test file" > temp.txt   #先清空,再写入
echo " demo test file2" >> temp.txt   #在文件末尾进行追加


将文件重定向到命令:

$ cmd < file


重定向内部文件块,使用<<EOF>...EOF之间的所有文本行都会成为stdin数据


使用tee来实现将数据重定向到文件,同时提供一份重定向数据的副本作为后续命令的stdin:

格式如下:
$ command | tee file1 file2


eg :

$ cat a* | tee out.txt | cat -n # tee 只能从stdin中读取


/dev/null,是特殊的设备文件,将接收到的任何数据都会被丢弃。null设备通常称为黑洞。

$ cmd 2>/dev/null # 将错误信息丢弃


5.3 自定义文件描述符

使用exec命令创建自定义文件描述符

文件打开模式:

只读模式(<从文件中读取至stdin)

$ echo a test line > testinput.txt
$ exec 3<testinput.txt
$ cat <&3
a test line


截断模式(>截断模式的文件写入)

$ exec 4>testoutput.txt
$ echo newline >&4
$ cat testoutput.txt
newline


追加模式(>>追加模式的文件写入)

$ exec 5>>testinput.txt
$ echo appended line >&5
$ cat testinput.txt
a test line
appended line


6. 数组与关联数组

普通数组只能使用整数作为数组索引,关联数组则可以使用字符作为数组索引

6.1 定义普通数组

array_var=(1,2,3,4,5) 或
array_var[0]="1"
array_vat[1]="2"


6.2 操作数组一些方法

array_var[0]="1";
array_var[2]="2";
echo ${array_var[0]}   # 取索引为0的值
array_var[0]="1";
array_var[2]="2";
echo ${array_var[*]}   # 获取数组中所有值
array_var[0]="1";
array_var[2]="2";
echo ${array_var[@]}   # 获取数组中所有值
array_var[0]="1";
array_var[2]="2";
echo ${#array_var[*]}  # 打印数组长度


6.3 定义关联数组

declare -A ass_array
ass_array=([a]='100' [b]='200')
echo "the a is ${ass_array[a]}"
# 列出数组索引通过以下方式:
echo ${!ass_array[*]}


7. 使用别名

创建别名(临时的,关闭当前终端就失效):

alias new_command = 'command sequence'


放入~/.bashrc文件中,可以一直保持作用:

$ 'alias cmd="command sequence"' >> ~/.bashrc


字符\对命令实施转义,可以执行原来的命令:

$ \ command


8. 日期和延时

8.1 读取日期

$ date
$ date +%s      # 读取纪元时
1445323477
$ date --date "Mon Oct 19 23:43:43 PDT 2015" +%s    # 转换成纪元时


8.2 脚本中生成延时

$ sleep no_of_seconds
$ sleep 1   # 延时1秒


9. 调试脚本

9.1 启动跟踪调试shell脚本

$ bash -x script.sh


9.2 针对脚本部分命令与脚本进行打印输出

set -x : 执行时显示参数和命令
set +x: 禁止调试
set -v:当命令进行读取时显示输入
set +v:禁止打印输入


可以设置成#!/bin/bash -xv,即可启用调试功能。

9.3 将#!/bin/bash改成#!/bin/bash -xv,也可以启用调试功能

10. 函数和参数

10.1 定义函数:

funciton a() { statement; }
或
a() { statement; }


10.2 调用函数:

$ a;  # 执行函数
$ a arg1 arg2;  # 执行函数,并传递参数


10.3 参数传递,并由脚本进行访问:

# fname函数定义,访问函数参数的方法如下
fname() {
echo $1, $2; # 访问参数1和参数2,类似$n,指第n个参数
echo "$@"; # 以列表的方式一次性打印所有参数
echo "$*"; # 类似于$@,但是参数作为单个实体
return 0; # 返回值
}


10.4 其他

支持递归。

导出函数:export -f fname

10.5 读取命令序列输出

这些命令被称为过滤器(filter)。使用管道(|)可以连接每个一个过滤器:

$ cmd1 | cmd2 | cmd3
$ ls | cat -n > out.txt


采用子shell方式存储命令序列的输出:

# 子shell生成独立进程,不会对当前shell产生影响
$ cmd_output=$(ls | cat -n); echo $cmd_output
$ cmd_output=`ls | cat -n`; echo $cmd_output   # 效果同上


11. read

# 读取2个字符并存入var变量
$ read -n 2 var
$ echo $var

# 不回显方式读取
$ read -s var

# 显示提示信息
$ read -p "enter input: " var

# 在特定时限内读取
$ read -t timeout var

# 用定界符结束输入行
$ read -d delim_char var


12. 运行命令直到成功

12.1 定义函数

repeat() {
while true
do
$@ && return
done
}


更快捷的做法是:

repeat() { while :; do $@ && return; done }


增加延时:

repeat() { while :; do $@ && return; sleep 30; done }


13. 字段分隔符和迭代器

13.1 内部字段分隔符IFS,IFS是存储定界符的环境变量,当前shell环境默认使用的界定字符串。

oldIFS=$IFS;
IFS=":";
for item in $line; ......
IFS=$oldIFS


13.2 for 循环

for var in list; do commands; done;
for i in (1..10); do commands; done;
for((i=0; i<10; i++)) { commands; }


13.3 while 循环

while condition; do commands; done;


13.4 until 循环

x=0;
until [ $x -eq 9 ];     # [ $x -eq 9 ] is the condition
do let x++;
echo $x;
done;


14. 比较与测试

14.1 if, else if, else (可以进行嵌套)

if condition;
then
command;
fi


14.2 else if 和 else

if condition;
then
command;
elif condition;
then
command;
else
command;
fi


14.3 使用逻辑运算符方式

[ condition ] && action;   # 如果condition为真,则执行action
[ condition ] || action;    # 如果condition为假,则执行action


14.4 算术比较(注意空格)

[ $var -eq 0 ] or [ $var -eq 0 ]


操作符:-gt:大于。

-lt:小于。

-ge:大于或等于。

-le:小于或等于。

-eq:等于。

-ne:不等于。

14.5 逻辑与,逻辑或

[ $var -gt 1 -a $var -lt 10 ]   # -a 表示逻辑与
[ $a -eq 1 -o $b -ne 0 ]      # -o 表示逻辑或


14.6 文件系统相关判断

[ -f $file_var ]:如果给定的变量包含正常的文件路径或文件名,则返回真
[ -x $file_var ]:如果给定的变量包含的文件可执行,则返回真
...等等


14.7 字符串比较(最好使用双中括号)

[[ $str1 = $str2 ]] 或 [[ $str1 == $str2 ]]  # 判断是否相等
[[ $str1 != $str2 ]]   # 判断不相等
[[ $str1 > $str2 ]], [[ $str1 < $str2 ]]   #判断字母序
[[ -z $str ]]   #包含的是空字符,则返回真
[[ -n $str ]]   #包含的是非空字符,则返回真


14.8 使用&&和||也可以将多个条件进行组合

if [[ $str1 != $str2 ]] && [[ -z $str1 ]] || [[ -n $str2 ]]


14.9 使用test,可不用[]

if test $str1 = $str2    # 同 if [[ $str1 = $str2 ]]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux shell shell 脚本