shell-基础_Linux

shell编程特点

shell是Unix/Linux最重要的软件之一,目前最流行的shell被陈伟Bash,几乎所有的Linux和绝大部分的Unix都可以使用Bash。
shell是一个命令解释器,是介于操作系统内核与用户之间的一个绝缘层。准确地说,他也是一种强力的计算机语言,一个shell程序被称为一个脚本,
是一种容易使用的工具,它可以通过将公共程序,工具,和编译过的二进制程序粘合在一起来建立应用,事实上,所有的Unix命令和工具再加上公共程序,
对于test与循环结构,也会给脚本添加强力的支持和增加灵活性。shell脚本对于管理系统任务和其它的重复工作的历程来说,表现的非常好

shell脚本遵循典型的Unix哲学,就是把大的复杂的工程分成小规模的子任务,并且把这些部件和工具组合起来。

什么时候不使用shell脚本?

1、资源密集型的任务,尤其在需要考虑效率时(排序,hash等)
2、需要处理大任务的数学操作,尤其是浮点运算,精确运算,或者复杂的算术运算
3、有跨平台移植需求
4、负责的应用,在必须使用结构化编程的时候
5、对于安全有很高要求的任务,

/etc/shells 查看系统中的shell

[root@localhost ~]# cat /etc/shells 
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
[root@localhost ~]# 

chsh -l改变用户的shell

[root@localhost ~]# echo $SHELL       # 当前的shell
/bin/bash
[root@localhost ~]# 

bash的特性

TAB
history
!$
alt+
~/.bash_history
~/.bash_logout在用户退出的时候调用

alias别名 -- 命令过长复杂的时候可以用

grep --color=tty

alias gc='grep --color=tty'当前终端生效
alias 查看别名
[root@localhost ~]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
[root@localhost ~]# 
[root@localhost ~]# which rm
alias rm='rm -i'
    /usr/bin/rm
[root@localhost ~]# 

针对所有终端生效需要修改文件

[root@localhost ~]# vim /etc/bashrc 
[root@localhost ~]# 

shell显示带颜色的字体

\033[字体背景色;字体颜色m ANSI控制码 \033[0m 关闭所有属性

字体颜色: 30 - 37

[root@localhost ~]# echo -e "\033[31m 红色字 \033[0m"
 红色字 
[root@localhost ~]# echo -e "\033[32m 绿色字 \033[0m"
 绿色字 
[root@localhost ~]# 

字体背景颜色: 40 - 47

[root@localhost ~]# echo -e "\033[42;37m 黑底红字 \033[0m"
 黑底红字 
[root@localhost ~]# 

 改变提示符文件颜色

[root@localhost ~]# echo -e "\033[40;32m"
本来是黑底白字,现在变为黑底绿字

报警声音

[root@localhost ~]# echo -e "\007 the bell ring"
 the bell ring

掌握参数传递机制Xargs

xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具,它擅长将标准输入数据转换成命令行参数,xargs能够
处理管道或者stdin并将其转换成特定命令的命令参数。xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行,
xargs的默认命令时echo,空格是默认定界符。这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代
[root@localhost test]# vim test.txt
[root@localhost test]# cat test.txt 
a b c d e f g
h i j k l m n
o p q 
r s t 
u v w x y z
[root@localhost test]# cat test.txt | xargs
a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@localhost test]# 
[root@localhost test]# cat test.txt | xargs -n 3
a b c
d e f
g h i
j k l
m n o
p q r
s t u
v w x
y z
[root@localhost test]# echo "nameXnameXnameXname" | xargs -dX
name name name name
[root@localhost test]# echo "nameXnameXnameXname" | xargs -dX -n2
name name
name name
[root@localhost test]# 

shell脚本规范

创建脚本,脚本文件名以.sh 结尾,为了能够通过文件名进行分辨

#!/bin/bash
# 告诉系统下面的脚本用什么解释器解释
# 以井号开头的注释,介绍脚本的用途
查看磁盘使用情况
[root@localhost test]# df -h
文件系统                 容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root   17G  5.2G   12G   31% /
devtmpfs                 897M     0  897M    0% /dev
tmpfs                    912M     0  912M    0% /dev/shm
tmpfs                    912M  1.1M  911M    1% /run
tmpfs                    912M     0  912M    0% /sys/fs/cgroup
/dev/sda1               1014M  179M  836M   18% /boot
tmpfs                    183M  4.0K  183M    1% /run/user/42
tmpfs                    183M   36K  183M    1% /run/user/1000
tmpfs                    183M     0  183M    0% /run/user/0
[root@localhost test]# 

脚本从上到下依次解释,需要chmod +x赋予脚本可执行权限,root用户x权限,对于普通用户必须rx(读一行,执行一行)

脚本中某一条命令出错了,不影响后边的执行,shell是解释性程序,shell从脚本中取出每一行然后用bash解释,交给内核,有一条出错后边的继续运行。

变量的类型

shell的变量

Linux变量分为不同的种类,人为的分成了4种:

1、环境变量,系统启动的时候指定的一系列变量,这些变量可以直接拿过来使用,比如查看当前的用户,当前的shell,当前的家目录等等
[root@localhost test]# env
XDG_SESSION_ID=124
HOSTNAME=localhost.localdomain
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=10.0.0.1 50442 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/1
USER=root

echo可以显示某一个变量,shell认为变量所有的值都是字符,不区分字符类型

[root@localhost test]# echo $USER
root
[root@localhost test]# echo $SHELL
/bin/bash
[root@localhost test]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost test]# echo $HOME
/root
[root@localhost test]# 

set查看所有变量环境变量与非环境变量,用户登录时为用户指定的

[root@localhost test]# set

-n 不换行

[root@localhost test]# echo -n$UID
-n0
[root@localhost test]# echo -e "aaa\nbbb\n"
aaa
bbb

[root@localhost test]# 
[root@localhost test]# echo -e "aaa\tbbb\t"
aaa    bbb    
[root@localhost test]# 
2、第二种称为预定义变量,这也是系统预定义好的,预定义变量和执行程序或者操作名对应的参数相关,比如一个shell脚本也可以像命令一样执行,
shell也可以有对一个的一些参数,命令和对应的参数先关,这个也叫作预定义变量
[root@localhost test]# cat z.sh 
#!/bin/bash
echo '$0'=$0      #表示当前的进程名
echo '$*'=$*      #表示所有位置参数的内容
echo '$#'=$#      #表示位置参数的数量
echo '$$'=$$      #表示当前进程的进程好
echo '$!'=$!      #表示后台运姓的最后一个进程好
echo '$?'=$?      #表示命令执行后返回的状态
[root@localhost test]# 
[root@localhost ~]# ./z.sh z y g
-bash: ./z.sh: 权限不够
[root@localhost ~]# chmod 777 z.sh 
[root@localhost ~]# ./z.sh z y g
$0=./z.sh
$*=z y g
$#=3
$$=18030
$!=
$?=0
[root@localhost ~]# 
$# 位置参数的数量,判断超出规定参数的数量,报警。
$? 命令执行后的返回状态,0位执行正确,非0位执行错误,判断备份tar命令有没有执行成功
$$ 确认进程是否运行

变量的作用域

当前终端设置a=123,再开启一个新的终端,新开的bash是不生效的
当前进程的变量不会影响父进程的shell

脚本的运行方式

./z.sh
bash z.sh
source z.sh
.z.sh

前两个是一样的,后面的两种不一样,source和.使用当前的shell执行,不会生成子shell

source和.后面的命令如果没有外部命令就都当做内部命令来处理,如果是尾部命令就会产生子进程,改变子进程的状态,没有产生就在内部

子进程到父进程,子进程中定义的变量,父进程得不到,如果需要这样去做也可以,可以让子进程产生一个临时文件,然后父进程访问这个文件。不过不好,效率低

还可以通过配置文件,将产生的变量,给其他的shell使用,Linux给我们提供了几个文件

/etc/bashrc
/etc//profile
~/.bashrc
~/.bash_profile
~/.bash_logout

/etc/下的会对所有的用户生效,家目录下只影响单一一个用户。

bashrc打开新的bash就生效

profile必须是用户登录,还有就是打开整个图形界面

算式置换

[root@localhost ~]# echo $((10+20))
30
[root@localhost ~]# echo $[10+20]
30
[root@localhost ~]# expr 10+20
10+20
[root@localhost ~]# let a = 10 + 20
-bash: let: =: 语法错误: 期待操作数 (错误符号是 "=")
[root@localhost ~]# let a=10+20
[root@localhost ~]# echo $a
30
[root@localhost ~]# 

命令置换

[root@localhost ~]# date +%m%d
0831
[root@localhost ~]# a=`date+%m%d`
bash: date+%m%d: 未找到命令...
[root@localhost ~]# a=`date +%m%d`
[root@localhost ~]# a=$(date +%m%d)
[root@localhost ~]# `echo `echo ls``
ls
[root@localhost ~]# $(echo $(echo ls))
anaconda-ks.cfg  initial-setup-ks.cfg  Python-3.5.3.tgz  z.sh
Desktop         Python-3.5.3           test
[root@localhost ~]# a=123
[root@localhost ~]# b=$(echo \$$(echo a))
[root@localhost ~]# echo $b
$a
[root@localhost ~]# eval echo $b
123
[root@localhost ~]# 

变量置换

………………具体请百度。