[OS] Shell脚本
来源:互联网 发布:js禁止鼠标点击事件 编辑:程序博客网 时间:2024/06/05 13:26
Shell脚本是什么?
通俗的解释就是一堆Linux命令的逻辑化处理。
为什么要编写Shell脚本?
在做开发的时候,有的时候需要部署环境或者是打包发布,往往都需要在终端里敲好多的命令才能做一件事,但是如果每次部署都要敲一堆命令,那么效率是非常低的,也会使人感到烦躁。所以,我们可以编写Shell脚本,将要执行的命令写在一起,用的时候只需要运行一下脚本就一切都搞定了。
从第一行开始!
为了确保Shell脚本可以正常运行,请将下面一行代码写在Shell脚本的第一行:
#!/bin/bash
确保了脚本总是运行在bash中。
如何执行Shell脚本?
首先我们先新建一个简单的Shell脚本,让它输出 Hello World!
。
$ touch t.sh$ vi t.sh# Coding...$ cat t.sh#!/bin/bashecho Hello World!
(一)使用 bash ScriptName
执行Shell脚本:只需要对脚本有读的权限(chmod 444 ./t.sh
)
$ bash t.sh Hello World!
(二)像运行命令一样 ./ScriptName
执行Shell脚本:需要对脚本有执行权限(chmod 555 ./t.sh
)
$ ./t.shHello World!
(三)使用命令 source ScriptName
运行Shell脚本:同样要对脚本有执行权限
和前两种执行方式不同的是,前两种方式是在当前Shell中创建了一个子进程来执行相应的脚本,不会对父进程有影响,而命令 source
会在当前的Shell中执行相应的脚本,直接影响当前的进程。
$ source t.shHello World!
只输出 Hello World!
看不出来效果,我们在脚本文件中加入一行切换目录的命令:
#!/bin/bashcd ../echo Hello World!
分别使用第二种和第三种方式执行,看效果:
$ pwd/Users/yuchunyu97/Projects/www/Homework/os04/src/script# 第二种$ ./t.sh Hello World!$ pwd/Users/yuchunyu97/Projects/www/Homework/os04/src/script# 第三种$ source t.sh Hello World!$ pwd/Users/yuchunyu97/Projects/www/Homework/os04/src
pwd
命令可以显示当前所在的目录。
可以看出来第二种方式执行切换目录的命令并没有对当前的目录产生影响,而第三种方式使当前目录返回了上一级目录。
在终端输出 echo
、读取用户输入 read
# echo 命令介绍$ cat t.sh #!/bin/bash# 输出字符串echo "Hello World"# 输出字符串也可以不加双引号echo Hello World# 输出双引号 "echo \"Hello World\"# echo命令默认换行,使用 -n 可以设置不换行echo -n Please Input Something: # 读取用户输入,并存入变量read line# 输出存在变量里的字符串echo "Get It: $line"# 使用单引号 ' 可以将变量输出成字符串echo 'It is not a variable $line'# 使用反引号 ` 执行命令echo Current Time: `date`# 使用大于号 > 将输出重定向到文件echo This line is in a file > t.tmp$ ./t.sh Hello WorldHello World"Hello World"Please Input Something:Hi Shell ScriptGet It: Hi Shell ScriptIt is not a variable $lineCurrent Time: 2017年11月 3日 星期五 15时33分52秒 CST$ lst.sh t.tmp$ cat t.tmp This line is in a file
关于 echo
的详细介绍:Shell命令:echo 命令详解
# read 命令介绍$ cat t.sh#!/bin/bash# -p 显示提示信息,并且不换行# 可以同时接受多个值,以空格分隔read -p "Enter your name and age separated by Space: " name ageecho "Hi, $name. Your age is $age"# -t 限制用户的输入时间read -t 5 -p "You have 5 Seconds to input: " lineecho -e "\nYour input is: $line"# -s 可以不显示用户的输入read -s -p "Enter Password: " passwdecho -e "\nYour password is: $passwd"$ ./t.sh Enter your name and age separated by Space: Yuchunyu 20Hi, Yuchunyu. Your age is 20You have 5 Seconds to input: Your input is: Enter Password: Your password is: MyPassword
测试/判断命令 test
在Linux中执行判断时,如果正确则返回
0
,如果错误则返回1
。
$?
临时存储当前判断的结果。
语法:
test expression or [ expression ] or [[ expression ]]
使用表达式来测试文件状态:
-f <file> 是否为文件-d <file> 是否为目录-r <file> 是否有读权限-w <file> 是否有写权限-x <file> 是否有执行权限-s <file> 是否有非零大小
例:
$ chmod 444 t.tmp$ ls -l t.tmp-r--r--r-- 1 yuchunyu97 staff 23 11 3 15:39 t.tmp$ cat t.sh #!/bin/bashtest -f t.tmpecho Is an ordinary file? $?test -d t.tmpecho Is a directory? $?test -r t.tmpecho Is Readable? $?test -w t.tmpecho Is Writable? $?test -x t.tmpecho Is Executable? $?test -s t.tmpecho Has Non-Zero Length? $?$ ./t.sh Is an ordinary file? 0Is a directory? 1Is Readable? 0Is Writable? 1Is Executable? 1Has Non-Zero Length? 0# 0 表示有# 1 表示无
字符串测试:
-n <string> 字符串是否不为空-z <string> 字符串是否为空<string> == <string> 字符串是否相等<string> != <string> 字符串是否不相等
例:
$ cat t.sh #!/bin/bashtest -n ""echo Empty String is not empty? $?test -z ""echo Empty String is empty? $?test "str" == "str1"echo \"str\" and \"str1\" are equal? $?test "str" != "str1"echo \"str\" and \"str1\" are not equal? $?$ ./t.sh Empty String is not empty? 1Empty String is empty? 0"str" and "str1" are equal? 1"str" and "str1" are not equal? 0
算数测试:
<value> -eq <value> 是否相等<value> -ne <value> 是否不相等<value> -lt <value> 是否小于<value> -le <value> 是否小于等于<value> -gt <value> 是否大于<value> -ge <value> 是否大于等于
例:
$ cat t.sh #!/bin/bashtest 1 -eq 2echo 1 equals 2? $?test 1 -ne 2echo 1 not equals 2? $?test 7 -lt 7echo 7 less than 7? $?test 7 -le 7echo 7 less than or equal 7? $?test 7 -gt 6echo 7 greater than 6? $?test 7 -ge 6echo 7 greater than or equal 6? $?$ ./t.sh 1 equals 2? 11 not equals 2? 07 less than 7? 17 less than or equal 7? 07 greater than 6? 07 greater than or equal 6? 0
&& 和 ||
可以用于有条件的执行命令。
command1 && command2如果command1成立,再执行command2command1 || command2如果command1不成立,再执行command2
例:
# 查看当前目录,有文件 t.tmp$ lst.sh t.tmp# 如果有 t.tmp,就删除# 如果没有 e.file,就新建一个 e.file$ cat t.sh #!/bin/bash(test -f t.tmp) && rm -f t.tmp(test -f e.file) || touch e.file# 执行脚本$ ./t.sh# 查看当前目录, t.tmp被删除了,新建了一个 e.file$ lse.file t.sh
if
命令
语法:
if [ status(true) ]then processelif [ status(true) ]then processelse processfi
注: if
和 elif
后面的空格不能省略,还有后面的 [ status ]
中,status两边的空格也不能省略。别忘了在最后加 fi
。
例:
$ cat t.sh #!/bin/bashread -p "Please input a number: " numif [ $num -lt 10 ]then echo $num is less than 10elif [ $num -gt 10 ]then echo $num is greater than 10else echo $num is equal to 10fi$ ./t.sh Please input a number: 22 is less than 10$ ./t.shPlease input a number: 1212 is greater than 10$ ./t.shPlease input a number: 1010 is equal to 10
case
命令
语法:
case $var in pattern1) command1 ;; pattern2) command2 ;; *) command3 ;;esac
注:每一个 pattern
后面有两个分号 ;;
,最后要加 esac
。
例:
$ cat t.sh #!/bin/bashread -p "Please input \"yes\" or \"no\": " varcase $var in [Yy][Ee][Ss]) echo Your input is YES;; [Nn][Oo]) echo Your input is NO;; *) echo Input Error;;esac$ ./t.sh Please input "yes" or "no": YesYour input is YES$ ./t.shPlease input "yes" or "no": noYour input is NO$ ./t.shPlease input "yes" or "no": helloInput Error
while
命令
语法:
while staues(true)docommands[break][continue]done
例:
$ cat t.sh #!/bin/bashguess=37while truedo read -p "Please input a number to guess: " num if [ $num -eq $guess ] then echo Bingo! It\'s $num break elif [ $num -lt $guess ] then echo Please guess a bigger number. continue elif [ $num -gt $guess ] then echo Please guess a smaller number. continue fidone$ ./t.sh Please input a number to guess: 30Please guess a bigger number.Please input a number to guess: 40Please guess a smaller number.Please input a number to guess: 35Please guess a bigger number.Please input a number to guess: 37Bingo! It's 37
注:Shell脚本中给变量赋值时,等号 =
两边不能有空格。
for
命令
语法:
for identifier in listdocommands to be executed on $identifierdone
例:
$ cat t.sh #!/bin/bashfor i in {1..10}do echo $idone$ ./t.sh 12345678910$ cat t.sh#!/bin/bashfor i in 1 2 3 0 6do echo $idone$ ./t.sh 12306$ cat t.sh#!/bin/bashfor i in cat dog pigdo echo $idone$ ./t.sh catdogpig$ cat t.sh #!/bin/bashfor i in `ls ../`do echo $idone$ ./t.sh a.outscriptsh.c
Shell脚本的参数
在命令行上的参数传递给Shell脚本,被存在了特殊的变量里。
语法:
$1, $2, $3 ... 依次代表传给Shell脚本的参数$@ 代表 "$1" "$2" "$3"$* 代表 "$1 $2 $3"$# 储存参数的个数
例:
$ cat t.sh #!/bin/bashecho First parameter: $1echo Second parameter: $2echo Number of parameters: $#echo $@echo $*$ ./t.sh one two three four fiveFirst parameter: oneSecond parameter: twoNumber of parameters: 5one two three four fiveone two three four five
shift
命令:位置参数可以用 shift
命令左移。比如 shift 3
表示原来的 $4
现在变成 $1
,原来的 $5
现在变成 $2
等等,原来的 $1
、 $2
、 $3
丢弃, $0
不移动。不带参数的 shift
命令相当于 shift 1
。
例:
$ cat t.sh #!/bin/bashwhile [ $# -gt 0 ]do echo 第一个参数为:$1 shiftdone$ ./t.sh 1 2 3 4 5第一个参数为:1第一个参数为:2第一个参数为:3第一个参数为:4第一个参数为:5
这个命令可以让我们逐个的处理命令行参数。
算数相关的命令
可以使用 let
或者 $(( expr ))
来执行算数运算。
例:
$ cat t.sh #!/bin/bashlet x=7+8echo $xecho $(( (6 + 8)*9 ))$ ./t.sh 15126
也可以使用命令 expr
。不过这个比前两个慢很多。注意使用 (
、 )
、*
的时候需要转义。
$ echo `expr 3 + 5`8$ expr 3 * ( 3 + 5 )zsh: unknown file attribute: # ( 、)、* 需要转义$ expr 3 \* \( 3 + 5 \)24
函数
语法:
function func_name() { statements [return]}
例:
$ cat t.sh #!/bin/bashfunction show() { echo "hello , $1"}show world$ ./t.sh hello , world
- [OS] Shell脚本
- [OS] Shell脚本练习
- mac os shell脚本hello world
- 常用的 Mac OS shell脚本和控制台命令
- Mac OS X终端执行Shell脚本的技巧
- Mac OS X Shell 脚本和终端命令
- [OS] Shell
- python调用Shell脚本:os.system(cmd)或os.popen(cmd),
- python调用Shell脚本:os.system(cmd)或os.popen(cmd)
- python调用Shell脚本:os.system(cmd)或os.popen(cmd)
- python调用Shell脚本:os.system(cmd)或os.popen(cmd)
- python调用Shell脚本:os.system(cmd)或os.popen(cmd)
- python调用Shell脚本:os.system(cmd)或os.popen(cmd)()【转】
- python调用Shell脚本:os.system(cmd)或os.popen(cmd)的区别
- python调用Shell脚本:os.system(cmd)或os.popen(cmd)
- python调用Shell脚本:os.system(cmd)或os.popen(cmd)
- python调用Shell脚本:os.system(cmd)或os.popen(cmd)【转】
- python调用Shell脚本:os.system(cmd)或os.popen(cmd)
- 使用Scanner时的一个注意事项
- 将全志R16平台上的MIPI屏迁移到全志R40平台上(草稿)
- Python的Socket
- 拉格朗日乘子法、KKT条件、线性规划对偶理论
- JAVA内存分配分析/栈内存、堆内存
- [OS] Shell脚本
- Linux下设置环境变量
- LVM原理及PV、VG、LV、PE、LE关系图
- bzoj1567[JSOI2008]Blue Mary的战役地图 二分+矩阵hash
- Lua汇总
- MVP简单登录实现
- ValueError: Input contains NaN, infinity or a value too large for dtype('float32').
- Handler 3秒跳转
- 11月03日解题报告