Shell - ShenYj/ShenYj.github.io GitHub Wiki
- 指定命令解读器 如:#!/bin/bash
- 注释 :说明某些代码的功能
- 可执行语句 :功能语句
一个.sh脚本执行的时候会先检查用户是否拥有该程序的执行权限
- 无:”Permission denied“ 提示
- 有:创建一个新的进程并执行语句
但是,Mac OSX 也是基于Unix 的 通常会同时安装多个Shell程序(sh,bash,csh等)
而不同的Shell程序语法有一定区别,到底使用哪个来执行代码系统无法正确判断,或者会默认调用执行导致执行结果并非我们期待的结果。
所以,Shell规定 “#!” 标识后面指定解释器的绝对路径 以方便创建指定解释器进程,解释并执行当前脚本。
Shell只支持单行注释 表示方法是#号
但是并不是说就只能用单行注释了 通过:« 后面写参数 ,但是要和结尾部分的参数想同 成对。
:<<xxx
echo "-----"
xxx
- 授权,直接执行
chmod +x setup.sh
”` 然后./setup.sh
- 调用Shell脚本的解释器来执行
/bin/bash setup.sh
- 通过source命令执行
source setup.sh
每个命令都会返回一个退出状态码 退出状态码是一个整数,有效范围是0~255,通常情况下,成功的命令返回0,而不成功的命令返回非0值。
我们也可以根据逻辑判断 主动exit 错误码到shell
变量名称 | 说明 |
---|---|
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。 |
$? | 上个命令的退出状态,或函数的返回值 |
$$ | 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID |
$_ | 保存之前执行的命令的最后一个参数 |
$! | 后台运行的最后一个进程的 ID 号 |
e.g.
#!/usr/bin/env bash
echo "$@"
输出结果
Mac $ ./setup.sh a "b,c"
a b,c
pwd
代表的是Print Working Directory
(打印当前目录)。如它的名字那样,pwd
会打印出当前工作目录,或简单的来说就是当前用户所位于的目录。它会打印出以根目录 (/)为起点的完整目录名(绝对目录)。这条命令是一条shell内建命令,并且在大多数shell中都可以使用,如bash、Bourne shell,ksh、zsh等等
-
dirname
可以获取一个文件所在的路径输出已经去除了尾部的”/”字符部分的名称;如果名称中不包含”/”,则显示”.”(表示当前目录)。
有时候,我们需要知道当前执行的输出shell脚本的所在绝对路径,可以用
dirname
实现dirname "$PWD" /Users/shenyj/Documents/Code/MyProject/DashLine
-
basename
它与dirname相反,是取得文件名称部分
❯ basename "$PWD" scripts
-
${a}
: 变量a
的值,在不引起歧义的情况下可以省略大括号 -
$(cmd)
: 命令替换,和cmd
效果相同 -
$()(exp)
: 增强括号的用法和expr exp
效果相同,计算数学表达式exp
的数值,其中exp
只要符合c
语言的运算规则即可,甚至三目运算符和逻辑表达式都可以计算。可以省略$
。-
e.g.
for((i=0;i<5;i++>)) # 如果不使用双括号 for i in seq 0 4 for i in {0..4} if (($i<5>)) # 如果不使用双括号 if [ $i -lt 5 ]
-
-
(cmd1;md2;cmd3)
: 新开一个子shell顺序执行命令cmd1
、cmd2
、cmd3
,各命令之间用分号隔开,最后一个命令后可以没有分号 -
{ cmd1;md2;cmd3;}
: 在当前shell顺序执行命令cmd1
、cmd2
、cmd3
,各命令之间用分号隔开,最后一个命令必须有分号,第一脚命令和左括号之间必须用空格隔开 -
shell里面的中括号(包括
[]
和[[]]
)可用于一些条件的测试:-
算数比较,比如一个变量是否为0:
[ $var -eq 0 ]
-
文件属性测试,比如一个文件是否存在:
[ -e $var ]
-
是否是目录, 比如:
[ -d $var ]
-
[[]]
: 字符串比较,增强括号用法,双括号中的表达式可以使用&&
、||
、<
、>
等语法,比如:# 比较两个字符串是否相同 [[ $var1 = $var2 ]] if [[ $a != 1 && $a != 2 ]] # 如果不使用 [[]] if [ $a -ne 1] && [$a != 2 ] if [ $a -ne 1 -a $a != 2 ]
-
对于
{}
和()
而言,括号中的重定向符只影响该条命令,而括号外的重定向符影响到括号中的所有命令
首先,单引号和双引号,都是为了解决中间有空格的问题
因为空格在 shell 中作为一个典型的分隔符,比如stringl=this is astring
,这样执行就会报错。为了避免这个问题,因此就产生了单引号和双引号,
他们的区别在于
- 单引号将剥夺其中的所有字符的特殊含义
- 双引号中的
$
(参数替换)和反引号(命令替换与$()
作用一样)是例外。 - 反引号的作用和
$(命令)
是一样的,但是反引号非常容易和单引号搞混,所以推荐使用$(命令)
所以,晾着基本上没有什么区别,除非在内容中遇到了参数替换符$
和命令替换符反引号
e.g.
-
单引号
echo '$PWD' $PWD
-
双引号
❯ echo “$PWD” “/Users/shenyj/Documents/Code/MyProject/DashLine/scripts”
-
反引号
❯ echo `PWD` /Users/shenyj/Documents/Code/MyProject/DashLine/scripts