Shell 脚本入门及语法速查

为什么80%的码农都做不了架构师?>>>   hot3.png

[TOC]


1. Hello World

1.1. 基本结构

创建 helloWorld.sh 文件,写入如下内容:

#!/bin/bashecho "hello world"

其中 #! 告诉系统其后路径所指定的程序是解释此脚本文件的 Shell 程序,常见的 Shell 程序有以下几类(可通过命令 cat /etc/shells 查看):

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)
  • ……

其中 Bash 在日常工作中被广泛使用,同时也是大多数 Linux 系统默认的 Shell。

执行该 sh 脚本

# 增加可执行权限
➜  chmod u+x helloWorld.sh# 运行脚本
➜  ./helloWorld.sh
或
➜  sh hellowWorld.sh

1.2. 注释

单行注释

  • # 开头的行是注释

多行注释

  • 方式一:用一对 {} 括起来,定义成一个函数,没有地方调用即达到注释的效果。

  • 方式二:

    :<<EOF
    注释内容...
    注释内容...
    注释内容...
    EOF
    

2. 基本语法

2.1. 变量

  • 变量定义

    • 变量名建议大写;
    • 有效字符仅能包含字母、数字、下划线,首个字符不能以数字开头;
    • = 两边不能有空格;
    • 不能使用标点符号;
    • 不能使用 bash 里的关键字(可用 help 命令查看保留关键字)。

    如下示例:

    VAR1="whoru"
    VAR2=100
    var3=/data/www
    var4_name="root"
    
  • 访问变量 $VAR1$(var1),其中,加花括号是为了帮助解释器识别变量的边界。

  • 设置变量只读 readonly VAR1

  • 删除变量(不适用于只读变量!unset VAR1

2.2. 字符串

  • 值用双引号 "" 或单引号 '' 表示
    • 单引号单限制:
      • 单引号里的任何字符都会原样输出;
      • 单引号字符串中的变量是无效的;
    • 双引号的优点:
      • 双引号里可以有变量;
      • 双引号里可以出现转义字符;
  • 其它
    # 字符串拼接 
    name="xiaoming"
    var2="hello, "$name # 输出 hello, xiaoming# 获取字符串长度
    string="abcd"
    echo ${#string} # 输出 4# 提取子字符串
    msg="zhangsan is a good man"
    echo ${msg:1:4} # 输出 hang
    

2.3. 数组

  • bash 支持一维数组(不支持多维数组),并且没有限定数组的大小。

  • 数组元素的下标由 0 开始,获取数组元素要用到下标。

  • 定义:

    array1=(value0 value1 value2 value3)或array2[0]=value0
    array2[1]=value1
    array2[2]=value2
    
  • 读取

    # 指定下标的元素
    echo ${array2[2]}; // 输出 value2# 获取数组所有元素
    echo ${array2[*]}; // 输出 value0 value1 value2
    echo ${array2[@]}
    
  • 获取数组元素个数

    echo ${#array2[@]}; // 输出 3
    echo ${#array2[*]};
    
  • 取得数组中指定下标元素的字符长度

    echo ${#array2[2]};
    

2.4. 传递参数

在执行 Shell 脚本时,可以向脚本传递参数,脚本内获取参数的格式为 $n,这里的 n 指传递给脚本的第 n 个参数。

如下脚本文件 demo.sh

#!/bin/bashecho "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";

执行该文件,并传递参数,如下:

➜  ./demo3.sh param1 param2 param3
执行的文件名:./demo3.sh
第一个参数为:param1
第二个参数为:param2
第三个参数为:param3

其中,$0 是一个特殊变量,代表当前脚本文件名,还有几个类似的变量如下:

变量说明
$#传递给脚本的参数个数。
$*以一个单字符串的形式显示所有向脚本传递的参数,如 "$1 $2 ... $n"
$@$* 相同,但是使用引号把每个参数包裹起来,如 "$1" "$2" ... "$n"
$?最后一个执行的命令的退出状态:0 正常;1 或其它任何值,表示有错误
$$脚本运行的当前进程ID号
$!最后一个后台命令的进程号。

3. 运算符

3.1. 算数运算符

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

假定有两个变量:a=10 b=20

运算符说明举例
+加法`expr $a + $b` 结果为 30。
-减法`expr $a - $b` 结果为 -10。
*乘法`expr $a \* $b` 结果为 200。
/除法`expr $b / $a` 结果为 2。
%取余`expr $b % $a` 结果为 0。
=赋值a=$b 将把变量 b 的值赋给 a。
==用于比较两个数字是否相同[ $a == $b ] 返回 false。
!=用于比较两个数字是否不相同[ $a != $b ] 返回 true。

注意

  • 表达式和运算符之间要有空格,如 2+2 是错误的,必须写成 2 + 2;
  • 完整的表达式要被反引号 ` ` 包裹起来;

3.2. 关系运算符

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

假定有两个变量:a=10 b=20

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

3.3. 布尔操作符

假定有两个变量: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。

3.4. 逻辑运算符

假定有两个变量:a=10 b=20

运算符说明举例
&&逻辑的 AND[[ $a -lt 100 && $b -gt 100 ]] 返回 false
||逻辑的 OR[[ $a -lt 100 || $b -gt 100 ]] 返回 true

3.5. 字符串运算符

假定有两个变量:a="abc" b="efg"

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

3.6. 文件测试运算符

运算符说明(如果是,则返回 true)举例
-b检测文件是否是块设备文件[ -b $file ]
-c检测文件是否是字符设备文件[ -c $file ]
-d检测文件是否是目录[ -d $file ]
-f检测文件是否是普通文件(既不是目录,也不是设备文件)[ -f $file ]
-g检测文件是否设置了 SGID 位[ -g $file ]
-k检测文件是否设置了粘着位(Sticky Bit)[ -k $file ]
-p检测文件是否是有名管道[ -p $file ]
-u检测文件是否设置了 SUID 位[ -u $file ]
-r检测文件是否可读[ -r $file ]
-w检测文件是否可写[ -w $file ]
-x检测文件是否可执行[ -x $file ]
-s检测文件是否为非空(文件大小是否大于0)文件[ -s $file ]
-e检测文件(包括目录)是否存在[ -e $file ]

4. 流程控制

4.1. if 语句

大多使用关系运算符检查关系

# 语法格式
if condition1
thencommand1...
elif condition2
thencommand2
elsecommandN
fi

4.2. case 语句

# 语法格式
case 值 in模式1)command1command2...commandN;;模式2)command1command2...commandN;;*)commandDefault;;
esac

4.3. while 语句

用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:

# 语法格式
while condition
docommand
done

4.4. until 循环

执行一系列命令直至条件为 true 时停止,它与 while 循环 在处理方式上刚好相反。

# 语法格式
until condition
docommand
done

4.5. for 循环

# 语法格式
for var in item1 item2 ... itemN
docommand1command2...commandN
done

4.6. 无限循环

# 语法1
while :
docommand
done# 语法2
while true
docommand
done# 语法3
for (( ; ; ))

4.7. 退出循环

  • break 跳出整个循环,执行循环体后面的代码,支持 break n 退出多层嵌套循环
  • continue 结束当前循环,同样支持 continue n 退出多层

5. 输入、输出重定向

5.1. 命令列表

命令说明
command > file将输出结果重定向到 file。
command < file将输入重定向到 file。
command >> file将输出以追加的方式重定向到 file。
n > file将文件描述符为 n 的文件重定向到 file。
n >> file将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m将输出文件 m 和 n 合并。
n <& m将输入文件 m 和 n 合并。
<< tag将开始标记 tag 和结束标记 tag 之间的内容作为输入。

关于文件描述符:

  • 0 通常是标准输入(STDIN),Unix程序默认从 stdin 读取数据。
  • 1 标准输出(STDOUT),Unix程序默认向 stdout 输出数据。
  • 2 标准错误输出(STDERR),Unix程序会向 stderr 流中写入错误信息。

示例:

# 将 stdout 和 stderr 合并后重定向到 file
➜  command > file 2>&1

5.2. /dev/null 文件

这是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,也什么也读不到。我们通常将命令的输出重定向到它,起到“禁止输出”的效果。

如:

# 屏蔽 stdout 和 stderr
➜  command > /dev/null 2>&1

5.3. Here 文档

# 将两个 delimiter 之间的内容(document) 作为输入传递给 command。
command << delimiter
document
delimiter

说明:

  • 结尾的 delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
  • 开始的 delimiter 前后的空格会被忽略掉。

6. 函数

6.1. 基本语法

[ function ] funcName [()] {command;[return int;]}

说明:

  • function 关键字非必须;
  • 如果该函数不传入变量,这函数名的后面的括号可以不加;
  • return 非必须;默认返回最后一条命令的执行结果;
  • 调用函数仅使用其函数名,如 funcName
  • 所有函数在使用前必须定义,即函数调用必须要在函数声明之后。

6.2. 函数参数

func() {echo "第一个参数为 $1 !"echo "第二个参数为 $2 !"...echo "第十个参数为 ${10} !"...
}# 调用并传参
func param1 param2 param3

说明

  • 在函数体内部,通过 $n 的形式来获取参数的值,例如:$1 表示第一个参数,$2 表示第二个参数;
  • 当 n >= 10 时,需要使用 ${n} 来获取参数。

7. 其它

7.1. echo 命令

用于字符串的输出,基本格式 echo string

使用示例:

# 显示普通字符
echo "It is a test" # 输出 It is a test# 显示转义字符
echo "\"It is a test\"" # 输出 "It is a test"# 显示变量
#!/bin/sh
NAME="xiaoming" 
echo "$NAME It is a test" # 输出 xiaoming is a test# 显示换行
echo -e "OK! \n" # -e 开启转义
echo "It is a test"# 显示不换行
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo "It is a test"# 显示结果定向至文件
echo "It is a test" > myfile# 显示命令执行结果
echo `date`

7.2. printf 命令

模仿 C 程序库(library)里的 printf() 程序,主要用于格式化输出。

默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n

其基本语法格式为:

printf  format-string  [arguments...]

说明:

  • format-string 为格式控制字符串
  • arguments 为参数列表。

示例:

➜  printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg  
➜  printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 
➜  printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 
➜  printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876 
姓名     性别   体重kg
郭靖     男      66.12
杨过     男      48.65
郭芙     女      47.99

其中:

  • %s %c %d %f 都是格式替代符;
  • %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
  • %-4.2f 指格式化为小数,其中.2指保留2位小数。

更多使用示例:

# 没有引号也可以输出
➜  printf %s abcdef# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
➜  printf %s abc def
abcdef➜  printf "%s\n" abc def
abc
def# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
➜  printf "%s and %d \n" and 0

7.3. test 命令

用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试(详见第3节对应的运算符部分)。

基本使用示例:

cd /bin
if test -e ./bash
thenecho '文件已存在!'
elseecho '文件不存在!'
fi

7.4. 包含文件

被包含的文件不需要可执行权限。

# 方式一
. another_file.sh# 方式二
source another_file.sh

更新:https://github.com/whorusq/linux-learning/edit/master/shell_basic_guide.md

转载于:https://my.oschina.net/antsky/blog/2353354

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/22628.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 文件管理命令

复制文件 命令(copy)&#xff1a; cp 源文件 目标文件/文件夹 cp -r 源文件夹 目标文件夹删除命令 命令(remove)&#xff1a; rm 文件1 文件2 文件2 ... rm -rf 文件夹1 文件夹2...远程连接 SSH 用于进行Linux的远程操作, 其原理为: 打包命令 tar 打包命令 tar -czvf 文…

jy-13-LINUX——Linux

目录&#xff1a; 1、day01-Linux-什么是Linux 2、day02-Linux-文件管理命令 3、day03-Linux &#xff0d;Windows SSH 客户端工具 4、Linux&#xff0d;下载命令wget 5、在linux下启动tomcat命令 张闹&#xff1a; 1、day01-Linux-什么是Linux 是一个OS&#xff0c;是Uni…

mysql数据库insert语句怎么写_mysql数据库中的insert语句解决方案

mysql数据库中的insert语句 数据库t_users中&#xff0c;包括三个字段user_id,user_name,user_password 其中 user_id设置为自动递增 为了实现注册功能 注册想就有两项 用户名和 密码 我写的sql语句是&#xff1a; insert into t_users values (?,?); 表明插入用户名和密码两…

修改Xshell字体大小和颜色

博客专区 > XManager的博客 > 博客详情 修改Xshell字体大小和颜色 XManager 发表于7个月前 分享到&#xff1a; 一键分享 QQ空间 微信 腾讯微博 新浪微博 QQ好友 有道云笔记 原 修改Xshell字体大小和颜色 收藏 XManager 发表于 7个月前阅读 849收藏 1点赞 0 评论 1 …

抽象类和抽象方法

抽象类 抽象类只能被继承&#xff0c;无法直接实例化。避免被直接实例化调用&#xff0c;相当于半成品&#xff0c;不能拿来直接使用。抽象方法 抽象方法只能定义&#xff0c;无法写方法体。后续继承后重写。 public abstract class Person{String name;int age;public void w…

基于openai打造公司内部知识库问答机器人

ChatGPT概念 OpenAI是一家AI研究和部署公司&#xff0c;开发了一个针对普通用户的ChatGPT的免费对话式AI机器人产品&#xff0c;该产品基于GPT-3.5模型&#xff0c;同时也推出了一个付费的ChatGPT Plus产品&#xff0c;该产品基于GPT-4模型。很明显&#xff0c;在国内是使用不…

稚晖君刚拿了百度投资,估值被曝已超独角兽

衡宇 发自 凹非寺 “华为天才少年”稚晖君创业项目&#xff0c;刚被百度风投投了&#xff01; 量子位获悉&#xff0c;稚晖君创业项目智元机器人&#xff0c;日前完成了第三轮融资&#xff0c;市场估值被曝在十几亿美元左右。 天眼查App显示&#xff0c;本轮新增股东包括李彦宏…

40亿个QQ号,限制1G内存,如何去重?

40亿个QQ号&#xff0c;限制1G内存&#xff0c;如何去重&#xff1f; 40亿个unsigned int&#xff0c;如果直接用内存存储的话&#xff0c;需要&#xff1a; 4*4000000000 /1024/1024/1024 14.9G &#xff0c;考虑到其中有一些重复的话&#xff0c;那1G的空间也基本上是不够用…

一次读完半本「三体」!GPT-4最强竞品突然升级10万token,啃论文代码演示全搞定...

视学算法报道 编辑&#xff1a;编辑部 【导读】GPT-4 32K还没用上&#xff0c;ChatGPT最强竞品已经秒读「了不起的盖茨比」了。 在GPT-4 32K还在内测阶段&#xff0c;OpenAI的劲敌直接把上下文长度打了上去。 就在今天&#xff0c;初创公司Anthropic宣布&#xff0c;Claude已…

自从Notion有了AI……

“Notion AI是一款极其强大且易于使用的工具&#xff0c;可以帮助您整理知识&#xff0c;撰写文档和记录笔记。它为您提供了一个可以实现简单快捷导航的用户界面&#xff0c;使您可以轻松访问和管理所有的文件和资源。它还提供了一系列强大的功能&#xff0c;包括个性化定制&am…

100 美元“骗走” 15% 股份?估值 10 亿美元的创业独角兽 Stability AI 联合创始人起诉 CEO...

整理 | 屠敏 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 2022 年 8 月&#xff0c;一款名为 Stable Diffusion 的开源文本生成图像模型横空出世&#xff0c;惊艳四座。 一定程度&#xff0c;它的出现加速了 OpenAI 想更早推出 ChatGPT 的决心。 而就是这样一款…

HTML情人节表白代码,给女朋友的电子情书代码,女朋友表白代码

HTML情人节表白代码&#xff0c;给女朋友的电子情书代码&#xff0c;女朋友表白代码,可更换照片及表白内容。 使用方法 1、表白对话在assets/dialog.json 2、女朋友照片放在img中&#xff0c;直接替换即可 3、代码包需要放在WEB服务器里运行&#xff0c;本地用浏览器直接打开…

一封来自Java程序员的情书

点击上方“程序员小灰”&#xff0c;选择“置顶公众号” 有趣有内涵的文章第一时间送达&#xff01; 本文转载自公众号 Hollis 一直以来程序员都给大家以高智商低情商&#xff0c;不懂得浪漫不会哄女生开心的形象。但是&#xff0c;我觉得程序员都是浪漫的。对于这种错误观念&…

Python表白妙招,把情书写进她的照片里

前言 我的好兄弟们&#xff0c;2022年可算是过去了&#xff0c;这不马上要过年了吗 就是说&#xff0c;各位兄弟有对象了吗&#xff0c;没有的回家还要面对亲戚的各种提问 退一步来说&#xff0c;有心仪的人吗&#xff0c;如果有的话&#xff0c;就来看看这篇 程序员的表白小…

为生信写的Python简明教程 | 视频3

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

生信入门一对一,数据操作带你飞

前段时间有个朋友问了我一个问题&#xff0c;“如何从一个大的 FASTA 文件中提取给定的一系列基因的 ID”&#xff0c;她用 ChatGPT搜索了问题&#xff0c;拿到了代码&#xff0c;发给我看了下&#xff0c;ChatGPT写的确实好&#xff0c;刚开始学的人估计都写不了这么好&#x…

在生信中利用Chat GPT/GPT4

论文链接Ten Quick Tips for Harnessing the Power of ChatGPT/GPT-4 in Computational Biology | Papers With Code 之前在paper with code上比较火的一篇文章&#xff0c;最近要给生科的学长学姐们个分享所以把这个翻了翻&#xff0c;原文自认为废话比较多&#xff0c;于是选…

一只产品汪的低代码学习之路(一):ChatGPT眼中的低代码有多牛?

写在前面 作为一只本科财务&#xff0c;研究生信管半路出家的产品汪 “啥也不懂”和“就会写写SQL”已经成为了我工作属性的代名词 “可以但没必要”“you can you up&#xff0c;no can no bibi”“你到底懂不懂”是开发拒绝我的三板斧。 秉承着不蒸馍馍争口气的优良传统&…

【差异表达分析】差异表达分析标准不标准化这是一个问题(含其其它报错问题)

前言 在一开始学习基因差异表达分析时&#xff0c;老师就强调用raw count做差异分析&#xff0c;相关文献和资料我也保存了不少&#xff0c;我之前弄清楚log2/cpm与count fpkm等不是在一个水平上讨论的问题&#xff0c;但是具体用的时候还是要栽个跟头才能印象深刻。 我在复现…

PointNet++阅读笔记

&#xff08;PointNet是PointNet结构的改良&#xff0c;它增强了对点云模型细节的捕捉能力&#xff09; 摘要&#xff1a;PointNet并没有捕捉到点云的局部结构&#xff0c;而本文介绍了一种分层神经网络&#xff0c;用于捕捉点云的局部特征。 Introduction 背景&#xff1a;…