Welcome everyone

shell 初步学习

linux 汪明鑫 885浏览 0评论

前言

以前看过一点

工作中一次没用过,昨天刚好整理了一篇lua的文章

今天写了点二分查找,顺势搞下shell,有备而无患

怼就完事了!

 

什么是shell

官方语言:

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

 

真正能够控制计算机硬件(CPU、内存、显示器等)的只有操作系统内核(Kernel),图形界面和命令行只是架设在用户和内核之间的一座桥梁。

 

由于安全、复杂、繁琐等原因,用户不能直接接触内核(也没有必要),需要另外再开发一个程序,让用户直接使用这个程序;该程序的作用就是接收用户的操作(点击图标、输入命令),并进行简单的处理,然后再传递给内核,这样用户就能间接地使用操作系统内核了。你看,在用户和内核之间增加一层“代理”,既能简化用户的操作,又能保障内核的安全

 

Shell 是一个应用程序,它连接了用户和 Linux 内核,让用户能够更加高效、安全、低成本地使用 Linux 内核,这就是 Shell 的本质。

 

 

可以将 Shell 在整个 Linux 系统中的地位描述成下图所示的样子。注意“用户”和“其它应用程序”是通过虚线连接的,因为用户启动 Linux 后直接面对的是 Shell,通过 Shell 才能运行其它的应用程序。

 

 

 

shell脚本

shell脚本就是一个文本,由一组linux命令组成,达成一些功能和目的

这样这个脚本就可以重用,不用每次都敲一堆命令

通过备用不同的脚本方便工作

 

shell 和 shell script 是两个不同的概念

 

举例

startZK.sh
#!/bin/sh

echo "start my zookeeper cluster"
for i in 1 2 3
do
ssh mini$i "source /etc/profile;/root/apps/zookeeper-3.4.5/bin/zkServer.sh start"
done

 

上面是一个自动启动zookeeper的脚本,不用每次都去服务器手动开启

直接执行脚本,通过ssh去登陆服务器,启动zk

开头统一需要 #!/bin/sh

echo 输出

for i in 1 2 3
do
 循环语句

去登陆mini1 ,mini2 ,mini3 3台服务器

这个例子给我们对shell的直观感受,

如果觉得上面这个例子不好理解,来个最简单的hello world,万物皆可hello world

 

vi test.sh

#!/bin/bash
echo "Hello World !"

运行脚本

sh test.sh

 

基础语法

注释:

#

 

变量的定义和使用:

myname="xinye"
echo ${myname}

 

变量类型:

运行shell时,会同时存在三种变量:

1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

 

特殊变量:

变量 含义
$0 当前脚本的文件名。
$n(n≥1) 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是 $1,第二个参数是 $2。
$# 传递给脚本或函数的参数个数。
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数。当被双引号" "包含时,$@ 与 $* 稍有不同
$? 上个命令的退出状态,或函数的返回值
$$ 当前 Shell 进程 ID

 

字符串:

可以用单引号,也可以用双引号

单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;

双引号里可以有变量

 

myname="xinye"
echo ${myname}

hello="wmx $myname shuaiqi!"
echo ${hello}

 

获取字符串长度:

echo ${#myname}

 

提取子字符串:

# 第二个开始截取3个
echo ${myname:1:3}

 

数组:

#!/bin/bash

arr=(3 4 6 8 9 14)

echo ${arr[1]}

#输出所有元素@
echo ${arr[@]}

#输出元素个数
echo ${#arr[@]}

arr=(3 4 6 8 9 14) 注意数组的定义没有逗号,而且是()不是[]。。。我刚才就踩坑了,带逗号

 

算术运算符:

#!/bin/bash

val=`expr 2 + 2`
echo $val

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

表达式和运算符之间要有空格m完整的表达式要被 ` ` 包含

 

关系运算符:

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。

 

布尔运算符:

下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。

 

字符串运算符:

下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:

运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否为0,不为0返回 true。 [ -n “$a” ] 返回 true。
$ 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

 

if-else:

a=10
b=20
if [ $a == $b ]
then
   echo "a 等于 b"
elif [ $a -gt $b ]
then
   echo "a 大于 b"
elif [ $a -lt $b ]
then
   echo "a 小于 b"
else
   echo "没有符合的条件"
fi

 

for:

for e in 1 2 3 4 5
do
 echo ${e}
done

for循环打印出1~5

 

while:

int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done

while循环打印出1~5

 

函数:

demoFun(){
    echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
# 调用函数
demoFun
echo "-----函数执行完毕-----"

 

函数还接受参数的输入

funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

 

shell内建命令

由 Bash 自身提供的命令,而不是文件系统中的某个可执行文件

内建命令会比外部命令执行得更快,执行外部命令时不但会触发磁盘 I/O,还需要 fork 出一个单独的进程来执行,执行完成后再退出。而执行内建命令相当于调用当前 Shell 进程的一个函数。

 

如cd就是shell内建命令

[root@xinyeshuaiqi shell]# type cd
cd is a shell builtin

 

命令 说明
: 扩展参数列表,执行重定向操作
. 读取并执行指定文件中的命令(在当前 shell 环境中)
alias 为指定命令定义一个别名
bg 将作业以后台模式运行
bind 将键盘序列绑定到一个 readline 函数或宏
break 退出 for、while、select 或 until 循环
builtin 执行指定的 shell 内建命令
caller 返回活动子函数调用的上下文
cd 将当前目录切换为指定的目录
command 执行指定的命令,无需进行通常的 shell 查找
compgen 为指定单词生成可能的补全匹配
complete 显示指定的单词是如何补全的
compopt 修改指定单词的补全选项
continue 继续执行 for、while、select 或 until 循环的下一次迭代
declare 声明一个变量或变量类型。
dirs 显示当前存储目录的列表
disown 从进程作业表中刪除指定的作业
echo 将指定字符串输出到 STDOUT
enable 启用或禁用指定的内建shell命令
eval 将指定的参数拼接成一个命令,然后执行该命令
exec 用指定命令替换 shell 进程
exit 强制 shell 以指定的退出状态码退出
export 设置子 shell 进程可用的变量
fc 从历史记录中选择命令列表
fg 将作业以前台模式运行
getopts 分析指定的位置参数
hash 查找并记住指定命令的全路径名
help 显示帮助文件
history 显示命令历史记录
jobs 列出活动作业
kill 向指定的进程 ID(PID) 发送一个系统信号
let 计算一个数学表达式中的每个参数
local 在函数中创建一个作用域受限的变量
logout 退出登录 shell
mapfile 从 STDIN 读取数据行,并将其加入索引数组
popd 从目录栈中删除记录
printf 使用格式化字符串显示文本
pushd 向目录栈添加一个目录
pwd 显示当前工作目录的路径名
read 从 STDIN 读取一行数据并将其赋给一个变量
readarray 从 STDIN 读取数据行并将其放入索引数组
readonly 从 STDIN 读取一行数据并将其赋给一个不可修改的变量
return 强制函数以某个值退出,这个值可以被调用脚本提取
set 设置并显示环境变量的值和 shell 属性
shift 将位置参数依次向下降一个位置
shopt 打开/关闭控制 shell 可选行为的变量值
source 读取并执行指定文件中的命令(在当前 shell 环境中)
suspend 暂停 Shell 的执行,直到收到一个 SIGCONT 信号
test 基于指定条件返回退出状态码 0 或 1
times 显示累计的用户和系统时间
trap 如果收到了指定的系统信号,执行指定的命令
type 显示指定的单词如果作为命令将会如何被解释
typeset 声明一个变量或变量类型。
ulimit 为系统用户设置指定的资源的上限
umask 为新建的文件和目录设置默认权限
unalias 刪除指定的别名
unset 刪除指定的环境变量或 shell 属性
wait 等待指定的进程完成,并返回退出状态码

 

参考

https://www.runoob.com/linux/linux-shell.html
http://c.biancheng.net/view/706.html

 

转载请注明:汪明鑫的个人博客 » shell 初步学习

喜欢 (1)

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz