shell之路 shell核心语法【第一篇】shell初识
shell简介
1.Shell是Unix的脚本语言,是与 Unix/Linux 交互的工具,shell使用的熟练程度反映了用户对Unix/Linux使用的熟练程度
2.Shell是系统命令+程序逻辑的的集合
3.Shell脚本和编程语言很相似
4.shell还不止一种?
常见的有四种:bash、sh、csh、ksh
我们学的是bash(全称:Bourne Again shell)
因为大多数Linux/UNIX默认是bash
5.怎么查看用户使用的是哪种shell?查看/etc/passwd文件就OK了 ?
我的系统的root用户的shell是bash
用户可以指定使用的shell类型,nologin代表用户不能使用shell和登陆
shell环境搭建
环境选择
shell环境在Linux系统上,首先我们需要一台Linux系统。这里你可以用虚拟机或者真实机器装一台Linux系统,发行版任意,可以是Centos、Redhat、Ubuntu、ArchLinux等等,你甚至可以在安卓手机上下载一个shell软件。
缩进设置
Linux的一个Tab键默认缩进8个空格,这里设置成4个,为了编码方便,以后每次缩进就可以按Tab就行了,Shell对缩进其实没有要求,这样设置纯属为了代码格式简洁清晰
打开配置文件
vim /etc/vimrc 或 vim ~/.vimrc
前者时系统范围配置文件,后者是个人配置文件
设置tab为4个空格
set ts=4
设置shift+>为4个空格
set smartindent set shiftwidth=4
关闭当前连接,重新登录Linux后生效
编码规范
我们一般是windows,这样就会有很多问题,因为windows的换行符是\r\n,Linux的换行符是\n,Tab和空格也要注意,因此采用专业的编辑器很重要
1.编辑器:Notepad++,设置换行符为Unix,Tab设置为4个空格
(设置换行符没有设置为Unix,要使用dos2unix filename命令,把文件格式化成unix格式(把换行符换成\n))
2.从编辑器粘贴到vi编辑器
直接复制粘贴会有缩进错乱的问题
在vi编辑器输入:set paste再复制粘贴就不会出现缩进混乱的问题了
本教程环境
为了方便,本教程使用云服务器,每次直接使用远程登录工具连接登录就行了
美化cat命令
由于只有vim命令可以看彩色的内容,为了看彩色内容用vim命令还得进入vi退出vi太麻烦,因此用彩色版的cat
wget https://github.com/jingweno/ccat/releases/download/v1.1.0/linux-amd64-1.1.0.tar.gz # 如果下载不下来用代理,你懂得,然后其他的不是amd64位发行版本的看这里 https://github.com/jingweno/ccat/releases #接着解压 tar -zxvf linux-amd64-1.1.0.tar.gz #移动到二进制文件目录 cd linux-amd64-1.1.0 sudo mv ccat /usr/local/bin #接着给这个文件赋予可执行权限 sudo chmod +x /usr/local/bin/ccat 之后就可以和cat一样执行命令了
现在ccat就是彩色的cat。
如果你觉得ccat比cat好,而且我以后不想使用cat了,想用ccat来代替cat,那么我就可以设置一个别名
vim ~/.bashrc
alias cat='ccat'
source ~/.bashrc
第一个shell程序
代码
vi t1.sh(文件名任意取,后缀可以不为.sh) #t1.sh在/tmp目录下
#!/bin/bash echo "hello shell"
执行方式
source 在当前shell内去读取、执行a.sh,而a.sh不需要有"执行权限",source命令可以简写为"." sh/bash 打开一个subshell去读取、执行a.sh,而a.sh不需要有"执行权限"。通常在subshell里运行的脚本里设置变量,不会影响到父shell的。 ./ 打开一个subshell去读取、执行a.sh,但a.sh需要有"执行权限"。可以用chmod +x添加执行权限。这里使用文件名直接执行(路径可以是相对路径可以是绝对路径,一般用./)
父子shell
父shell
我们登录服务器后,默认在一个shell中,默认初始化一堆变量给当前用户,这和windows的默认系统变量一样
子shell
Linux的shell和windows的cmd一样,都是一个软件,或者说一个程序,子shell就是子程序,子程序默认继承或者说复制父进程的所有变量子进程的变量和父进程的变量是无关的,父进程的变量影响子进程,子进程不影响父进程
如何进入子shell?
方式一:sh/bash filename或者./ filename
方式二:在终端,命令bash或者sh可进入子shell
#!/bin/bash
#!/bin/bash什么作用?解释器
上图可知,shell脚本有两种执行方式,sh和bash是一种(centos系统下,sh是bash的软连接,软连接类似于windows下的快捷方式),./和完整的.sh文件路径是另一种,这两种执行方式的区别在于,前者可以省略#!/bin/bash。
#!/bin/bash,后者则不可省略,因为后者通过#!/bin/bash调用bash解释器。前者的sh .sh的sh已经显式的指定了解释器;但是共同点是两者都要在.sh所在的目录操作(完整的.sh文件路径除外)。
so over!!
注释
单行注释 #注释
多行注释(BLOCK为字符或数字) :<< BLOCK 注释 BLOCK
变量
为什么使用变量
1.代码简洁:当某个数据被频繁使用或者很长的时候,最好使用变量代替
#!/bin/bash a='hello shell' # 字符串可以使用单引号或者双引号 b="hello shell" echo $a # 引用变量的结果:使用美元符+变量名 echo $b ####输出 [root@hy shellScripts]# sh t1.sh hello shell hello shell
2.获取命令的输出
`cmd` 或者$(cmd)可获得命令的输出结果,需要注意的是`cmd`兼容性更强,部分unix系统可能不能正常使用$(cmd)
#!/bin/bash a=`pwd` b=`ls` echo $a echo $b ###输出 [root@hy shellScripts]# sh t1.sh /root/wulei/shellScripts t1.sh
变量定义
1.系统自带变量是大写
2.自定义变量:
变量名可以是字母、数字(不能是首字符)、下划线的组合
变量赋值时,等号的两侧不能留有空格(否则报语法错误)
等号右边和数据之间有空格
变量使用
1.$变量名
2.${变量名} # 更易于阅读和理解
a=`pwd` # 或者a=$(pwd) history_command=`ls` echo $a echo $history_command echo ${history_command} ###输出 [root@hy shellScripts]# sh t1.sh /root/wulei/shellScripts t1.sh t1.sh
变量长度
特殊变量列表
$* 和 $@ 的区别:
当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;
"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
#!/bin/bash echo "\$*=" $* echo "\$*=" "$*" echo "\$@=" $@ echo "\$@=" "$@" echo "print each param from \$*" for var in $* do echo "$var" done echo "print each param from "\$@"" for var in $@ do echo "$var" done echo "print each param from \$*" for var in "$*" do echo "$var" done echo "print each param from "\$@"" for var in "$@" do echo "$var" done
[root@hy ~]# ./1.sh a b c d $*= a b c d $*= a b c d $@= a b c d $@= a b c d print each param from $* a b c d print each param from $@ a b c d print each param from $* a b c d print each param from $@ a b c d [root@hy ~]#
转义字符
\c 不换行
#!/bin/bash a=10 echo -e "Value \t of a is \n$a"
异常
如果某行代码出现语法错误,程序退出; 如果是Linux命令出错,程序不退出,继续执行
正常代码
#!/bin/bash a=3 if [ $a -gt 2 ];then echo "大于2" fi echo $a ###输出 [root@hy shellScripts]# sh t1.sh 大于2 3
Linux命令错误
语法错误
输出
echo(自动换行;双引号可省略)
#!/bin/bash name=world echo hello $name echo "hello $name"
printf(不会自动换行;)
printf 命令用于格式化输出, 是echo命令的增强版。它是C语言printf()库函数的一个有限的变形,并且在语法上有些不同。
#!/bin/bash read -p "please input:" input printf "%s \n" "you input $input"
输入
使用变量接收
read 输入(-p -t) ##-p输入时的提示字符;-t多久不输入shell程序就退出
#!/bin/bash read -p "please input:" input echo you input $input
$REPLY
如果不使用变量接收输入的数据,数据会存到变量REPLY
#!/bin/bash read -p "please input:" echo "you first input $REPLY" read -p "please input:" echo "you second input $REPLY"