shell的基本使用

小知识:

在bash环境中变量有各自的范围,有些的变量无法超出自己本身的范围,也无法更改自己,
或提升自己的能力范围
用source命令执行脚本,会对里面的变量发生改变包括范围
例:命令行中写name=wang 脚本中写name=xdg  先命令行,再脚本,最后命令行的顺序依次执行
1.正常的执行脚本 ./file.sh 
输出的结果: wang  xdg  wang
2.用source执行脚本  source ./file.sh 
输出的结果: wang  xdg  xdg 

常量的有效时间是等于进程的时间


例:name=xdg; (name=mage; echo $name; name=wang; echo $name); echo $name
结果:mage  wang  xdg
注:在括号或者是括号外的 ; 分号一定要注意!()表示的是开启一个子进程,
并不在当前的bash中,如果在()里写入exit命令,只会退出当前的(),而不会退出当前的脚本。
例:name=xdg; { name=mage; echo $name; name=wang; echo $name; }; echo $name
结果:mage  wang  wang
在{}里代表是一个匿名函数的形式,同样注意;的位置,还有{}边上的空格要有
里面修改了变量的值,同样在外面也有效

编程语言: 

低级:汇编 
高级:
编译:高级语言–>编译器–>目标代码 
java,C# 
解释:高级语言–>解释器–>机器代码 
shell, perl, python

格式要求:首行shebang机制 
#!/bin/bash 
#!/usr/bin/python 
#!/usr/bin/perl 
注:因为当前系统默认的为bash,所以可有可无,如果换了其它系统或环境
会导致运行出错,当前系统用的语言不一定是bash,所有还是把当前的环境给写出来。

shell脚本的用途有: 

自动化常用命令  
执行系统管理和故障排除  
创建简单的应用程序 
处理文本或文件

运行脚本  

给予执行权限,在命令行上指定脚本的绝对或相对路径 
直接运行解释器,将脚本作为解释器程序的参数运行

脚本测试

检测脚本中的语法错误 
bash -n /path/to/some_script  
调试执行 
bash -x /path/to/some_script

强类型:变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。
一般定义变量时必须指定类型、参与运算必须符合类型要求;
调用未声明变量会产生错误 如 java,c#  
弱类型:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;
参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用 
如:bash 不支持浮点数,php 

根据变量的生效范围等标准: 

本地变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,
包括当前shell的子shell进程均无效 
变量赋值:name=‘value’  
可以使用引用value: 
(1) 可以是直接字串:name=”root” 
(2) 变量引用:name=”$USER” 
(3) 命令引用:name=COMMAND 或 name=$(COMMAND) 
变量引用:${name}  $name 
注:有些时候要括起来,例:显示第10个数,不能写成$10,会识别成$1+0
 
“”:弱引用,其中的变量引用会被替换为变量值 
”:强引用,其中的变量引用不会被替换为变量值,而保持原字符串  
显示已定义的所有变量   :set  
删除变量: unset name
环境变量:生效范围为当前shell进程及其子进程 
变量声明、赋值: 
export name=VALUE 
declare -x name=VALUE  
变量引用:$name, ${name}  
显示所有环境变量: 
env 
printenv 
export 
declare -x  
删除变量: unset name
bash中内建的环境变量
PATH  命令执行查找路径
SHELL 当前系统的shell
USER  当前系统的UID(名字)
UID   当前系统的UID (数字)
HOME  当前系统的家目录
PWD  当前系统路径
SHLVL  当前进程的深度(查看 pstree )
LANG 当前系统的语言和编码  LANG=en_US.UTF-8
MAIL 当前用户的邮件家目录  MAIL=/var/spool/mail/root
HOSTNAME   当前系统的主机名
HISTSIZE  命令历史的最大长度
_ 上个命令的最后一个字符串 (下划线)
    注:如果有参数就是最后一个参数,如果没有则就是命令(最后一个字符串)
局部变量:生效范围为当前shell进程中某代码片断(通常指函数)

位置变量$1, $2, …来表示,用于让脚本在脚本代码 中调用通过命令行传递给它的参数 
位置变量在脚本代码中调用通过命令行传递给脚本的参数 
$1, $2, …:对应第1、第2等参数,
shift [n]换位置  注:就是把当前指向第一个数的指针,向后移动n位(这个是累加)
例:shift 2;shift 2;    这是移动了4位
$0: 命令本身   单单只是命令的本身,不带有任何的参数
$*: 传递给脚本的所有参数,全部参数合为一个字符串 
$@: 传递给脚本的所有参数,每个参数为独立字符串 
$#: 传递给脚本的参数的个数 
注: $@  $*  只在被双引号包起来的时候才会有差异,没有””是没有区别的 
注: set —   清空所有位置变量参数 
特殊变量:
$? 上个命令的执行的结果(正确执行 0  非正确执行 非0)
$$ 当前进程的PID  如:当前进程的父进程的PID: $PPID 
$-  例:echo $-  –> himBH
h:hashall,打开这个选项后,Shell 会将命令所在的路径 hash下来,避免每次都要查询。
  通过set +h将h选项关闭 
i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的 shell。
  所谓的交互式shell,在脚本中,i选项 是关闭的。 
m:monitor,打开监控模式,就可以通过Job control来控制 进程的停止、继续,后台或者前台执行等。
B:braceexpand,大括号扩展 
H:history,H选项打开,可以展开历史列表中的命令,可以 通过!感叹号来完成
  例如“!!”返回上最近的一个历史命令, “!n”返回第 n 个历史命令
只读变量:
声明只读变量: 
readonly name 
declare -r name  
查看只读变量: 
readonly –p

bash自定义退出状态码 

exit [n]:自定义退出状态码 
注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字 
注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

bash中的算术运算:help let 

+, -, *, /, %取模(取余), **(乘方) 
实现算术运算: 如: a=5  b=7  c
(1) let var=算术表达式
let c=a+b
(2) var=$[算术表达式] 
c=$[a+b]    比如:echo $[a+b]
(3) var=$((算术表达式)) 
c=$((a+b))  比如:echo $((a+b))
(4) var=$(expr arg1 arg2 arg3 …)
c=$(expr 2+3)
c=$(expr $a+$b)
注:如果单单的expr的写法,在下面
(5) declare –i var = 数值 
declare -i c=a+b
(6) echo ‘算术表达式’ | bc 
echo  $[a+b] | bc
echo  3+5 | bc
注:无法识别当中的变量
乘法符号有些场景中需要转义,如* 
注:1  expr 0 + 0  ——> echo $? ——> 1
注:0 + 0 之间必须要有空格表示出来,不然出错,再运算结果为0的话,运行的状态是有问题的(非0)
2  let i=0  echo $i  输出结果为:0 —> 但是程序的运行的状态 —> 是非0的
例:k=0;let k++;echo $?  —>输出的结果也是非0
   k=0;let ++k;echo $?  —>输出的结果也是0


bash有内建的随机数生成器:

$RANDOM(0-32767) 
echo $[$RANDOM%50] :0-49之间随机数

增强型赋值:

+=, -=, *=, /=, %= 
let varOPERvalue 
例如:let count+=3 
自加3后自赋值  
自增,自减: 
let var+=1 
let var++ 
let var-=1 
let var-

短路运算 
 短路与 
第一个为0,结果必定为0 
第一个为1,第二个必须要参与运算
 短路或 
   第一个为1,结果必定为1 
第一个为0,第二个必须要参与运算

异或:^ 异或的两个值,相同为假,不同为真
例:如何把两个整数变量的值给调换,而且不用第三者。
a=10; b=6; a=$[a^b]; b=$[a^b]; a=$[a^b];
    a  110011011            c  111001101
    b  001010110    —>    b  001010110   注:两者的运算的结果
异或c  111001101    异或结果a  110011011

测试命令: 注意:EXPRESSION前后必须有空白字符,格式要求。

test EXPRESSION  不支持
注:有些变量的时候,须要引号引起来才能判断出来
[root@centos7 ~]# aa=””
[root@centos7 ~]# echo $aa

[root@centos7 ~]# test $aa && echo true     为假
[root@centos7 ~]# test “$aa” && echo true   为假

[root@centos7 ~]# aa=” ”                 
[root@centos7 ~]# echo $aa

[root@centos7 ~]# test $aa && echo true     为假 
[root@centos7 ~]# test “$aa” && echo true   为真
true

[ EXPRESSION ]    不支持,里面的 <,>都需要转意
[root@centos7 ~]# unset a
[root@centos7 ~]# [ $a == “wang” ]
-bash: [: ==: unary operator expected  出错信息
[root@centos7 ~]# [ “$a” == “wang” ]   必须引号引起来
[root@centos7 ~]# 
例:有的地方会出来这种写法: [ X$a == X”wang” ] 或 [ X”$a” == X”wang” ]
上面两个都可以,第一个是,添加额外的字符,来判断。

注: [ id ] && { a=10; echo $a; } || echo Hello  在测试的时候{}外是没有;号的,并且{}里面的 空格 要有

[[ EXPRESSION ]]  支持正则表达式

根据退出状态而定,命令可以有条件地运行 
  &&  代表条件性的AND   THEN  
  ||  代表条件性的OR   ELSE 
  
-v VAR     
变量VAR是否设置 
数值测试: 
-gt 是否大于 
-ge 是否大于等于 
-eq 是否等于 
-ne 是否不等于 
-lt 是否小于 
-le 是否小于等于

字符串测试: 

== 是否等于 
>   ascii码是否大于ascii码 
<  是否小于 
!= 是否不等于 
=~ 左侧字符串是否能够被右侧的PATTERN所匹配 
注意: 此表达式一般用于[[  ]]中;扩展的正则表达式 
[root@centos6 xdg]# [[ $sh =~ “.*.sh$” ]]
[root@centos6 xdg]# echo $?              
1
注:在使用的时候必须要用[[]] 用到了正则表达式,中间的空格也不能少
例:[root@centos6 ~]# str=abc;[[ $str == “abc” ]] && echo tree
tree
[root@centos6 ~]# str=abc;[[ $str =~ “abc” ]] && echo tree 
tree
[root@centos6 ~]# str=abc;[[ $str =~ “^a” ]] && echo tree    
[root@centos6 ~]# str=abc;[[ $str =~ ^a ]] && echo tree  
tree

-z “STRING“ 字符串是否为空,空为真,不空为假 
[root@centos7 ~]# aa=xxx
[root@centos7 ~]# [ -z “$aa” ] && echo true  为假 
[root@centos7 ~]# [ -z ‘$aa’ ] && echo true  为假 
[root@centos7 ~]# aa=””
[root@centos7 ~]# [ -z ‘$aa’ ] && echo true  为假
[root@centos7 ~]# [ -z “$aa” ] && echo true  为真
true
-n “STRING“ 字符串是否不空,不空为真,空为假 
注意:用于字符串比较时的用到的操作数都应该使用引号,如上test一样


存在性测试 

-a FILE:同-e 
-e FILE: 文件存在性测试,存在为真,否则为假  
存在性及类别测试 
-b FILE:是否存在且为块设备文件 
-c FILE:是否存在且为字符设备文件 
-d FILE:是否存在且为目录文件 
-f FILE:是否存在且为普通文件 
-h FILE  或 -L FILE:存在且为符号链接文件 
注:在判断一个文件是否存在时,要先判断它是否是一个符号链接文件
-p FILE:是否存在且为命名管道文件 
-S FILE:是否存在且为套接字文件

文件权限测试:   测试文件,首先判断是否是软硬链接

-r FILE:是否存在且可读 
-w FILE: 是否存在且可写 
-x FILE: 是否存在且可执行 
文件特殊权限测试: 
-u FILE:是否存在且拥有suid权限 
-g FILE:是否存在且拥有sgid权限 
-k FILE:是否存在且拥有sticky权限

文件大小测试: 

-s FILE: 是否存在,且非空 
文件是否打开: 
* -t fd: fd表示文件描述符是否已经打开且与某终端相关 
-N FILE:文件自动上一次被读取之后是否被修改过 
-O FILE:当前有效用户是否为文件属主 
-G FILE:当前有效用户是否为文件属组

双目测试: 

FILE1 -ef FILE2: FILE1与FILE2是否指向同一个设备上的相同inode 
注:判断的是否是一个硬连接
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime) 
FILE1 -ot FILE2: FILE1是否旧于FILE2

第一种方式: 
COMMAND1 && COMMAND2 并且 
COMMAND1 || COMMAND2 或者 
! COMMAND   非 
 如:[[ -r FILE ]] && [[ -w FILE ]]  
第二种方式: 
EXPRESSION1 -a EXPRESSION2 并且 
EXPRESSION1 -o EXPRESSION2 或者 
! EXPRESSION 必须使用测试命令进行 
 

使用read来把输入值分配给一个或多个shell变量 

-p 指定要显示的提示 
-s 静默输入,一般用于密码 
-n  N 指定输入的字符长度N 
-d ‘字符’  输入结束符 
-t  N  TIMEOUT为N秒 
 read 从标准输入中读取值,给每个单词分配一个变量 所有剩余单词都被分配给最后一个变量 
 read -p “Enter a filename: “ FILE
 

注:在shell脚本中,运行的优先级

把命令行分成单个命令词
展开别名
展开大括号的声明({}) 
展开波浪符声明(~)
命令替换$() 和 “)
再次把命令行分成命令词
展开文件通配(*、?、[abc]等等)
准备I/0重导向(<、>)
运行命令

反斜线(\)会使随后的字符按原意解释 
$ echo Your cost: \$5.00 
Your cost: $5.00 
加引号来防止扩展  
单引号(’)防止所有扩展  
双引号(”)也防止所有扩展,但是以下情况例外:
$(美元符号) - 变量扩展
`(反引号) - 命令替换
\(反斜线) - 禁止单个字符扩展
!(叹号) - 历史命令替换


bash的配置文件

按生效范围划分,存在两类:  
全局配置: /etc/profile 
  /etc/profile.d/*.sh 
  /etc/bashrc  

个人配置: ~/.bash_profile 
  ~/.bashrc

shell登录两种方式

交互式登录: 
(1)直接通过终端输入账号密码登录 
(2)使用“su – UserName” 切换的用户 
 执行顺序:/etc/profile 
   –> /etc/profile.d/.sh 
   –> ~/.bash_profile 
   –> ~/.bashrc 
   –> /etc/bashrc 
非交互式登录: 
(1)su UserName 
(2)图形界面下打开的终端 
(3)执行脚本 
(4)任何其它的bash实例 
 执行顺序:~/.bashrc 
–> /etc/bashrc 
–> /etc/profile.d/
.sh
 
profile类
按功能划分,存在两类: 
profile类和bashrc类 
profile类:为交互式登录的shell提供配置 
全局:/etc/profile, /etc/profile.d/*.sh 
个人:~/.bash_profile 
功用: (1) 用于定义环境变量 
  (2) 运行命令或脚本
  
bashrc类
bashrc类:为非交互式和交互式登录的shell提供配置 
全局:/etc/bashrc 
个人:~/.bashrc 
功用: (1) 定义命令别名和函数 
  (2) 定义本地变量
  
编辑配置文件生效
修改profile和bashrc文件后需生效 
两种方法: 1重新启动shell进程 
 2 . 或source     
例: . ~/.bashrc

bash退出任务
保存在~/.bash_logout文件中(用户)在退出登录shell时运行用于 
创建自动备份 
清除临时文件

原创文章,作者:_xddggg,如若转载,请注明出处:http://www.178linux.com/83951

(0)
_xddggg_xddggg
上一篇 2017-08-05
下一篇 2017-08-05

相关推荐

  • N25第四周 chmod chown以及 grep命令的常用示例

    1、复制/etc/skel目录为/home/tuser1,要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限。     [root@localhost ~]# cp -r /etc/skel /home/tuser1   &n…

    Linux干货 2016-12-22
  • bash编程初体验(一)

    bash编程初体验(一) 认识bash编程 变量与赋值 算术与逻辑运算 条件测试与退出状态 认识bash编程 Bash(GNU Bourne-Again Shell)是许多Linux发行版的默认Shell,我们要认识的bash中,就是在bash的环境下的一种编程。 众所周知,程序=指令+数据,由此也决定了两种不同的编程风格,过程过与对象式; 过程式:以指令为…

    Linux干货 2016-08-15
  • Linux系统结构 详解

    Linux系统一般有4个主要部分: 内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。部分层次结构如图1-1所示。  1. linux内核         内核是操作系统的核心,具有很多最基本功能,它负责管理系…

    Linux干货 2015-04-13
  • 压缩、解压缩和归档工具

    1  compress和uncompress 用法:     compress [-dfvcVr] [-b maxbits] [file…] 选项:     -d   解压缩     -c   结果…

    Linux干货 2016-08-18
  • N25-Bazinga-第三周作业

    N25-Bazinga-第三周作业 1.列出当前系统上登录的所有用户的用户名,注意:同一个用户登录多次,则只显示一次即可。 [root@localhost ~]# w | cut -d' ' -f1 | uniq -c |&nbs…

    Linux干货 2016-12-21
  • corosync+pacemaker+pcs 使用ansible配置高可用LAMP构架

    前言: 这篇博客的实验主要是配置两个节点基于corosync + pacemaker的高考用lamp, 是我搞得最痛苦的一次,并且结果还不稳定。主要问题是corosync 1.x + pacemaker 时,如果把pacemaker当成插件使用,尝试很多次都不成功,后来把pacemaker当成半独立的服务进行配置。 但是如此一来crm就没办法进行资源配置,只…

    Linux干货 2016-01-27