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

相关推荐

  • Linux常用命令使用方法

    下面以一些常用的Linux命令为例讲解一下Linux命令的使用方法。 1.  ifconfig – 配置网络接口 | 对象 | 参数 | 含义 || —— | —— | —— |网卡名 | / | 查看指定网卡IP的地址,不指定默认查看所有网卡地址网卡名 | up …

    Linux干货 2017-09-01
  • 第三周作业

    1、列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可。 [root@localhost /]# who | cut -d ‘ ‘ -f 1  | sort -u root user1 或: [root@localhost /]# who | cut -d ‘ ‘ -…

    Linux干货 2017-02-24
  • Linux基础知识总结

    Linux基础知识 计算机系统 计算机硬件组成 1.控制器:计算机系统的控制中心,协调各部分工作,保证计算机按照预先规定的目标和步骤进行操作及处理。 2.运算器:对数据进行算数运算,逻辑判断以及数据的比较、移位等操作。 3.存储器:存取程序和各种数据信息。  4.输入设备:把信息,如数字、文字、图像等转换为数字形式的“编码”的设备(键盘,扫描仪) …

    2017-05-18
  • 马哥教育网络班22期第1周课程作业

    一、基础中的基础————–计算机的组成部分         计算机组成分为硬件系统与软件系统         硬件包括五个部分     1.控制器:控制器 I/O 存储器 &nbs…

    Linux干货 2016-08-15
  • linux用户管理

    linux用户:       linux用户大体分为两种:一是:管理员用户;二是普通用户,普通用户又可以分为系统用户和登录用户。因为linux是一个多用户多任务的系统,所以每一个要使用系统资源的用户,都要向管理员申请一个账号,使用这个账号登录到系统。每个用户都拥有一个自己的名字和密码,以登录到用户。 每个用户都有唯一的用户标识(…

    Linux干货 2016-08-04
  • 马哥教育网络21期+第四周作业博客

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

    Linux干货 2016-09-05