相关文章:
shell
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。
#!/bin/bash
echo “Hello World !”
! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
echo 命令用于向窗口输出文本。
运行 Shell 脚本有两种方法:
1、作为可执行程序
将上面的代码保存为 test.sh,并 cd 到相应目录:
chmod +x ./test.sh #使脚本具有执行权限
./test.sh #执行脚本
注意,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。
2、作为解释器参数
这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:
/bin/sh test.sh
/bin/php test.php
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。
这种方法会产生子shell,局部变量
Linux执行Scripts有两种方式,主要区别在于是否建立subshe
source filename or . filename
不创建subshell,在当前shell环境下读取并执行filename中的命令,相当于顺序执行filename里面的命令bash filename or ./filename
创建subshell,在当前bash环境下再新建一个子shell执行filename中的命令
子shell继承父shell的变量,但子shell不能使用父shell的变量,除非使用export
pstree查看后:
1 | [sunnyli@sunnyli ~]$ echo num=1 > test.sh |
./test.sh
或者bash test.sh
这种方式会启动一个新的子shell来执行test.sh
脚本。在子shell中执行完脚本后,会返回到原来的shell环境,但是子shell无法修改父shell的变量,所以在父shell中的num
仍然保持为原来的值。. test.sh
或者source test.sh
这种方式会在当前shell环境中直接执行test.sh
脚本,而不会启动一个新的子shell。因此,当脚本中对变量num
进行赋值时,会影响到当前shell环境中的num
变量的值,导致父shell中的num
被修改为脚本中所赋的值。
单双反引号
单引号所见即所得,直接显示单引号里的内容。
双引号则是先把变量解析之后,再输出。
反引号用于命令替换,即先执行反引号中的语句,再把结果加入到原命令中。
内外置命令
内置命令:在系统启动时就加载入内存,常驻内存,执行效率更高,但是占用资源
外置命令:系统需要从硬盘中读取程序文件,再读入内存加载
1 | [sunnyli@sunnyli ~]$ type cd |
变量
定义变量
定义变量时,变量名不加美元符号($,PHP语言中变量需要),如:
your_name=”runoob.com”
注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线 _。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。
使用变量
$在Linux shell编程中用于取变量值
使用一个定义过的变量,只要在变量名前面 加$ 即可,如:
your_name=”qinjx”
echo $your_name
echo ${your_name}
${变量} 返回变量值
${注释 #变量} 返回变量长度,字符长度
${变量:start} 返回变量start数值之后的字符,且包含start的数字
${变量:start:length} 提取start之后的length限制的字符,例如${name:4:1)
${变量#word} 从变量开头删除最短匹配的word子串
${变量##word} 从变量开头,删除最长匹配的word
${变量%word} 从变量结尾删除最短的word
${变量//pattern/string} 用string代替所有的pattern
${变量%%word} 从变量结尾开始删除最长匹配的word
${变量/pattern/string} 用string代替第一个的pattern
result=${parameter:-word}
如果parameter变量值为空,返回word字符串,赋值给result变量
result=${parametq:=word}
如果para变量为空,则word替代变量值,且返回其值
${parameter:?word}
如果para变量为空,word当作stderr输出,否则输出变量值用于设置变量为空导致错误时,返回的错误信息
${parameter:+word}
如果para变量为空,什么都不做,否则word返回
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
for skill in Ada Coffe Action Java; do
echo “I am good at ${skill}Script”
done
``可以带回指令的返回值,除了显式地直接赋值,还可以用语句给变量赋值,如:
for file in
ls /etc
或
for file in $(ls /etc)
命令行参数
以上语句将 /etc 下目录的文件名循环出来。
$1,$2…${10}获取命令行位置参数
$# 传递到脚本或函数的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$相同,但是使用时加引号,并在引号中返回每个参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。*函数返回值在调用该函数后通过$? 来获得。
这几个参数都通过命令行输入
只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
下面的例子尝试更改只读变量,结果报错:
#!/bin/bash
myUrl=”https://www.google.com"
readonly myUrl
myUrl=”https://www.baidu.com"
运行脚本,结果如下:
/bin/sh: NAME: This variable is read only.
删除变量
使用 unset 命令可以删除变量。语法:
unset variable_name
变量被删除后不能再次使用。unset 命令不能删除只读变量。
环境变量的加载顺序
输出
printf
和c类似
printf “%d %s\n” 1 “abc”
echo
echo “\“It is a test\“”
运算符
expr支持模式匹配 expr 1.jpg “:” “.* \ .jpg*”
echo $[5*3]
echo $(((2+3)-3))
echo `expr 3+3`
15
2
3+3
tr
tr只支持单个字符替换
1 | [sunnyli@sunnyli ~]$ echo {1..10} |tr " " " + " |
seq
生成一段序列
1 | [sunnyli@sunnyli ~]$ seq 10 |
条件测试
test
-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。
-e 文件名 如果文件存在则为真
-r 文件名 如果文件存在且可读则为真
-w 文件名 如果文件存在且可写则为真
-x 文件名 如果文件存在且可执行则为真
-s 文件名 如果文件存在且至少有一个字符则为真
-d 文件名 如果文件存在且为目录则为真-z 字符串 判断是否为空
-n 字符串 判断是否有
-f 文件名 如果文件存在且为普通文件则为真
-c 文件名 如果文件存在且为字符型特殊文件则为真
-b 文件名 如果文件存在且为块特殊文件则为真
[]
test和[]的作用是一样注意的点:中括号,前后的空格必须有。
在条件测试中使用变量,必须添加双引号[-n “$filename” ]
流程控制
所有的流程控制[ 条件 ] 条件两侧有空格
if
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
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
末尾的 fi 就是 if 倒过来拼写,后面还会遇到类似的
case
*case $变量名 in
“值”)
语句
;;
“值”)
语句
;;
)
语句
;;
esac
case $1 in
“1”)
echo “1”
;;
*)
echo ‘…’
;;
esac
for
for循环一般格式为:
for var in item1 item2 … itemN
do
command1
command2
…
commandN
donefor loop in 1 2 3 4 5
do
echo “The value is: $loop”
done
while
while condition
do
command
done#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let “int++”
done
以上实例使用了 Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量
函数
[ function ] funname [()]
{
action;
[return int;]
}funWithReturn(){
echo “这个函数会对输入的两个数字进行相加运算…”
echo “输入第一个数字: “
read -p “我是提示信息” aNum
echo “输入第二个数字: “
read anotherNum
echo “两个数字分别为 $aNum 和 $anotherNum !”
return $(($aNum+$anotherNum))
}
funWithReturn
echo “输入的两个数字之和为 $? !”