1.基本命令
touch 创建空文件(当然,你也可以使用echo >filename)
ln 创建链接符号(快捷方式|引用):
- 符号链接:ln –s
- 硬链接:ln
区别:
- 符号链接产生了一个快捷方式,是对源文件的一个链接。
- 硬链接是底层字节的链接,简单来说,相当于是一个文件,两个文件名,占用同一块扇区,好处是省空间,即便删除一个,只要还有硬连接,这个文件就依然存在。
ls –i 查看文件inode编号(唯一的,可以确认文件是否为同一个,类似于hash值)
mv 移动|重命名
file 查看文件(文件夹)类型等信息
cat 显示内容 -n:所有行号 ;-b:有字加行号;-T:不显示制表符;
more 按页显示;例如:cat xxx |more
tail 查看文件结尾;-n number(或-number):指定最后几行;-f:追踪,可以动态追踪日志文件。
head 与tail类似,不过没有-f参数
ps 进程
top 显示linux进程(Linux版任务管理器)
kill 干掉进程
df 查看硬盘空间
sort 文件内容排序
grep 搜索文本
$BASH_SUBSHELL 子shell检测变量
sleep timeCount(s)
句子结尾加&:后台模式运行
jobs 工作
(command 1;command 2…) 任务列表,可以同时执行
coproc 协程(后台有个子shell,执行你的命令,同时生成一个job)
which 查看命令程序所在位置
history 命令历史记录
!! 上一个历史命令(省着按向上箭头了)
!number 第n条历史命令被执行
11.1使用多个命令
$date;who // 命令列表,加入分号就可以,这样会依次执行。参见5.2.1节
注意区分$(date;who),这个是进程列表,会生成一个子shell来执行
Shell脚本的关键在于输入多个命令并处理每个命令的结果,甚至需要将一个命令的结果传给另外一个命令。
Shell可以让你将多个命令串起来,一次性完成。
上面的date;who可以写入一个文件,这样就不用在命令行敲命令了,运行这个文本文件就好了。
创建Shell脚本文件
显示消息
使用变量
反引号
重定向输入输出
管道
执行数学运算
退出脚本
shell脚本关键在于输入多个命令并且处理每个命令的结果,将一个命令结果传给另外一个命令。
2011-07-26 11:22 1071人阅读 评论(0) 收藏;) 举报
环境
printenv 查看环境变量(env只能查看所有的全局变量); 本命令支持查看某条变量(不需要加美元符号,echo需要)
set 查看|设置环境变量
export 到处变量为全局变量,就可以在各种shell中使用了(并不能使shell的父shell环境变量发生变化)
unset 删除环境变量
passwd (chpasswd) 密码查看|修改
umask 为文件分配默认权限
chmod 更改权限
chown 改变归属权
11.2 创建shell脚本文件
第一行必须这样:指定要使用的shell
#!/bin/bash
1.一般情况#用来注释的,但是第一行的#除外
比如写一个test,内容如下:
#!/bin/bash
date
who
如果想直接运行,需要将路径添加到PATH环境变量中去。
也可以当前目录直接./test,这样可能会没有权限。
chmod u+x test // 增加执行权限
接着就可以 ./test 运行了
两个命令在一起运行,用分号隔开
Shell脚本是Linux开发工作中常用的工具,但是我一直没有找到一个适合自己的简明扼要的HandBook。在工作过程中整理了一下,贴在这里已备查看。
分区
fdisk 分区;p:显示基本设备信息;n:new个分区;w:write进设备
mkefs 格式化ext分区;
mke2fs 格式化ext2分区;
mkfs.ext3 格式化ext3分区;
mkfs.ext4 格式化ext4分区;
mkreiserfs 格式化reiserfs分区
jfs_mkfs 格式化jfs分区
mkfs.xfs 格式化xfs分区
mkfs.zfs 格式化zfs分区
mkfs.btrfs 格式化btrfs分区
fsck 检查修复分区 -a:自动检测修复;-A:列出fstab中所有分区,并检测;-C:显示支持的文件系统检测时的进度条(ext2、3);-s:多个文件系统依次检查;
LVM 可以添加多个硬盘到一个卷组(整合为一个大分区也没有问题),可以创建快照,镜像。
如何创建LVM物理卷?使用fdisk t来改变分区类型(为8e);或使用pvcreate创建,pvdisplay查看创建进度;
vgcreate 创建卷组(为物理卷);例如:vgcreate Vol1 /dev/sda1;vgdisplay查看进度
lvcreate 创建逻辑卷;例如:lvcreate –l 100%FREE –n lvtest Vol1;lvdisplay查看进度
淡淡这样还不够!!!还要有文件系统,如ext4的LVM:mkfs.ext4 /dev/Vol1/lvtest。上述创建了一个ext4类型的逻辑卷lvtest。还要手动挂载:mount /dev/Vol1/lvtest /mnt/my_partation
LVM的一堆管理命令:
vgchange 激活和禁用卷组
vgremove 删除卷组
vgextend 将物理卷加到卷组中
vgreduce 从卷组中删除物理卷
lvextend 增加逻辑卷的大小
lvreduce 减小逻辑卷的大小
11.3 显示消息
想在脚本上加提示信息,可以直接这样:
#!/bin/bash
echo haha,I am xiaochongyong, data print:
date
echo “Let’s see who’s logged:”
who
如果想要输出单引号,需要加双引号把整句话括起来,否则会不正常。比如:
还可以这样:
echo命令可以用单引号或双引号来划定文本字符串。如果在字符串中用到了它们,需要在文本中使用一种引号,而用另外一种来将字符串划定起来
把文本字符串和 命令输出显示在同一行中。用 –n 参数:
#!/bin/bash
echo –n “The time and date are: ”
date
- 创建脚本文件的时候,必须将文件的第一行指定要使用的shell。其格式为:
echo 可以显示简单的文本字符串
2.shell编程
变量是宽松的定义,任何由字母、数字或下划线组成的文本字符串,长度不超过20个。用户变量区分大小写,所以变量 Var1 和变量 var1 是不同的。
shell编程最强大的地方在于可以从console的输出中取回这些输出,并随便利用,一旦这样做,则可以利用shell做任何事情了,只要你能在console中输出它。
如何从shell中获取输出的内容?两种方法:
- 反引号符号;
- $();
例如,使用date命令可以输出当前时间,如果写shell脚本的话,可以通过如下两种写法获取console的date:
1 date=$(date);
2 date=`date`;
字符串如果合并的话,直接各种引号,而不需要+或者其他的操作,如:
str1="string1";
str2="string2";
str3=$str1$str2;
输出或引用一个变量,则可以:
echo $str3;
输出重定向:>
在已有的文件中追加内容:>>
输入重定向:<
内联输入重定向:<<
管道:|
实际上,windows console中也支持管道.
例如,之前用more对console的内容进行分页:ls -al |more
既然是管道,必然支持很多管道,虽然可能只会用到两个
shell中计算:expr
例如计算1+2:
expr 1 + 2
#注意上式的空格,运算符间都是有的
arg1 |arg2 | 如果arg1既不是null也不是0,返回arg1;否则arg2 |
ARG1 & ARG2 | 如果没有参数是null或零值,返回 ARG1 ;否则返回 0 |
< | 如果 ARG1 小于 ARG2 ,返回 1 ;否则返回 0 |
<= | 如果 ARG1 小于或等于 ARG2 ,返回 1 ;否则返回 0 |
= | 如果 ARG1 等于 ARG2 ,返回 1 ;否则返回 0 |
!= | 如果 ARG1 不等于 ARG2 ,返回 1 ;否则返回 0 |
>= | 如果 ARG1 大于或等于 ARG2 ,返回 1 ;否则返回 0 |
> | 如果 ARG1 大于 ARG2 ,返回 1 ;否则返回 0 |
+ | |
- | |
* | |
/ | |
% | |
STRING : REGEXP | 如果 REGEXP 匹配到了 STRING 中的某个模式,返回该模式匹配 |
match STRING REGEXP | 如果 REGEXP 匹配到了 STRING 中的某个模式,返回该模式匹配 |
substr STRING POS LENGTH | 返回起始位置为 POS (从 1 开始计数)、长度为 LENGTH 个字符的子字符串 |
index STRING CHARS | 返回在 STRING 中找到 CHARS 字符串的位置;否则,返回 |
index STRING CHARS | 返回字符串 STRING 的数值长度 |
+ TOKEN | 将 TOKEN 解释成字符串,即使是个关键字 |
(EXPRESSION) | 返回 EXPRESSION 的值 |
需要注意,尽可能的把运算符号之前加上转义字符,否则很可能会导致expr收到错误!
例如 expr 1 * 2
所以,bash shell为了保持跟Bourne shell的兼容而包含了 expr 命令,但它同样也提供了一种更简单方法来执行数学表达式。在bash中,在将一个数学运算结果赋给某个变量时,可以用美元符和方括号( $[ operation ] )将数学表达式围起来。
这样,就相当方便了,还是1+2,则可以写成:
$[1+2]
而根本不需要考虑空格的问题~~~
这里需要注意的是,bash shell本身不支持浮点数运算,所以可以利用其他的方法:
bash计算器:bc;
使用bash需要注意,精度(scale)默认为0,所以需要设置:scale=0
bc本身支持定义变量
在脚本中使用bc:
echo “scale=4;1/2” |bc
# 或
echo “scale=4;print 1/2” |bc
更好的方法是使用内联输入重定向(<<):
#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=$(bc << EOF
scale = 4
a1 = ( $var1 * $var2)
b1 = ($var3 * $var4)
a1 + b1
EOF
)
echo The final answer for this mess is $var5
## EOF既是输入的开始,又是输入的结束,所以计算没有问题的
脚本退出命令:
exit exitCode
查看退出代码:
echo $?
退出代码意图:
0 命令成功结束
1 一般性未知错误
2 不适合的shell命令
126 命令不可执行
127 没找到命令
128 无效的退出参数
128+x 与Linux信号x相关的严重错误
130 通过Ctrl+C终止的命令
255 正常范围之外的退出状态码
11.4 使用变量
通常会需要在shell命令使用其他数据来处理信息,可以通过变量来实现。
变量允许你临时性的将信息存储在shell中,以便和脚本中的其他命令一起使用
#!/bin/bash
echo this is a test 可以不加双引号
但是如果字符串中有双引号的话,就要用其他引号将字符串圈起来
1 Shell中的特殊符号
条件结构:if,then,elif,fi
if command
#注意是command不是condition!
then
commands
elif command
then
commands
...
else
commands
...
if command
then
commands
fi
fi
#或
if command;then
commands
fi
11.4.1 环境变量
Shell维护着一组环境变量用来记录特定的系统信息。比如系统的名字,登录到系统的用户,UID等。
可以用set命令来显示一份完整的当前环境变量列表。
在脚本中可以在环境变量前加上美元符$来使用环境变量。
#!/bin/bash
# display Info
echo "User info for userid: $USER"
echo UID: $UID
echo HOME: $HOME
echo “The cost of the item is $15”
这样输出不了$,脚本会尝试显示$1的值,再显示5。应该在前面防止一个反斜杠
echo “The cost of the item is $15”
允许脚本将美元符解读为实际的美元符
运行脚本文件时要制定文件位置,还要赋予文件运行的权限:
echo "this is a test to see if you're paying attention"
1.1 $ 美元符号。用来表示变量的值。如变量NAME的值为Mike,则使用$NAME就可以得到“Mike”这个值。
test
如何是condition呢?答案是:
test,即if行由command 后面改为:
test condition
11.4.2 用户变量
Shell脚本还允许在脚本中定义和使用自己的变量。
定义变量允许临时存储数据并在脚本中使用,这样看起来更像是一个程序了。
用户变量可以是任何字母数字或下划线组成的文本字符串,长度不超过20个。区分大小写
使用=给用户变量赋值,变量=和值之间不能有空格
比如:
var=10
Var=2
Var3=testing
Var4=”hahaha”
Shell脚本会自动决定变量值的数据类型,在脚本整个生命周期里变量会一直保持它们的值,直到结束时会被删除掉。
也是用美元符引用。
也可以用变量对变量进行赋值,比如:
#!/bin/bash
age=22
name="xiaochongyong"
echo "Hi, i am $name, age $age"
echo "copy test2:"
age1=$age
name1=$name
echo "Hi, copy test i am $name1, age $age1"
chmod u+x file
在同一行显示一个文本字符串作为命令输出
1.2 # 井号。除了做为超级用户的提示符之外,还可以在脚本中做为注释的开头字母,每一行语句中,从#号开始的部分就不执行了。
数值比较
例如:
ret=1
if test ret -eq 1
then
echo ret is 1
fi
至于里面的-eq,则是判断条件的一种形式:等于。
test 命令的数值比较功能
说明
等效
n1 -eq n2
==
=
-ge
>=
>=
-gt
>
<
-le
<=
<=
-lt
<
<
-ne
!=
!=
test的另一种写法是:
[ condition ]
#注意方括号都和condition有空格的!!!
例如,将test子例改写一下,即:
ret=1
if [ ret -eq 1 ]
then
echo ret is 1
fi
test可以做:
数值比较
字符串比较
文件比较
11.4.3 命令替换
Shell脚本最有用的特性之一就是可以从命令输出中提取信息,并将其赋给变量。这样就可以随意在脚本中使用了。
有两种方法可以将命令输出赋值给变量
(1)反引用字符(` `)。美式键盘上在波浪线~同一个键位
(2)$() 格式:
#!/bin/bash
testing=`date`
echo -n "date is: $testing"
echo ""
testing2=$(date)
echo -n "date2 is: $testing2"
echo ""
下面这个就有意思了:
#!/bin/bash
# copy the /usr/bin directory listing to a log file
today=$(date +%y%m%d)
ls /usr/bin -al > log.$today
today是被赋予格式化之后的date命令的输出,这是提取日期信息来生成日志文件名常用的一种技术。
+%y%m%d格式告诉date命令将日期显示为两位数的年月日的组合
ls /usr/bin -al > log.$today 这里就重定向到一个文件中了。
注意:
命令替换会创建一个子shell来运行对应的命令。子shell所执行命令是无法使用脚本中所创建的变量的。
在命令行提示符下使用路径./也会创建出子shell。 比如:test3脚本中 ./test2
要是运行命令的时候不加入路径,就不会创建子shell。
如果使用的是内建shell命令就不会涉及子shell。
运行:./file
echo -n "the time and date are:"
之后输出的内容就会在一行
1.3 “” 双引号。shell不会将一对双引号之间的文本中的大多数特殊字符进行解释,如#不再是注释的开头,它只表示一个井号“#”。但$仍然保持特殊含义。(在双引号中的$加变量名,即:$PARAM_NAME,依然会转换成变量的值。)
字符串比较
str1=str2 | == |
!= | |
< | len |
> | len |
-n | len>0 |
-z | len=0 |
特别需要注意容易犯错误的地方在于符号会与bash本身的一些符号冲突而导致执行出错!!!包括:
<,>.
所以要进行转义,即:
>,<.
11.5 重定向输入和输出
- 显示消息:echo命令,比如:
使用变量,$PATH
1.3.1 双引号对于某些特殊符号是不起作用的, 例如:”,$,,`(反引号)
文件比较
-d file | 存在目录 |
-e file | exist |
-f file | 存在文件 |
-r file | read |
-s file | 文件空 |
-w file | write |
-x file | execute |
-O file | own |
-G file | group |
file1 -nt file2 | new than |
file1 -ot file2 | old than |
如何简单的获取条件判断时条件的结果呢?
test 1 = 1;echo $?
上句测试,为真,显示0
注意:test的两个参数,不应该在其中计算,而应该在之前的步骤完成,否则可能会得到错误的结果!!!(亲测)
例如:一定存在$HOME,所以test -e $HOME 必然为真(0)。
但是,假设$HOME中不存在123目录或文件夹,则test -e $HOME/123依然会返回0.
而按照我写的注意,写为x1=$HOME/123;test -e $1;echo $?则会返回1,即真实结果.
所以一定要注意这种情况!
11.5.1输出重定向
将命令的内容重定向到文件
Command > outfile
比如:who > test6 不存在则创建,存在则覆盖
pwd >> test6 这样会追加
#!/bin/bash
但是要使用美元符号,就要加反斜杠
echo "the cost of the item is $15"
1.3.2 双引号和单引号不能嵌套。即:echo ‘””’ 输出””, echo “’’” 输出’’
更多的条件:
&&,||
11.5.2 输入重定向
1.将文件的内容重定向到命令
小于号 <
wc命令可以对数据中的文本进行计数。
默认会输出文本的行数,文本的词数,文本的字节数
比如:
wc < test6
2.内联输入重定向:无需使用文件进行重定向,只需要在命令行中指定用户输入重定向的数据就可以了。
符号: <<
还需要指定一个文本标记来划分输入数据的开始和结尾,任何字符串都可以作为文本标记,但在数据的开始和结尾文本标记必须一致。
比如这样,输入xcy表示结束。Wc命令对内联输入重定向提供的数据进行行、词、字节数的计数,直到输入了作为文本标记的那个字符串。
echo "========请输入用户名========="
${variable}引用的变量,用来帮助识别美元符号后的变量
1.4 ‘’ 单引号。shell不会将一对单引号之间的任何字符做特殊解释。(在双引号中的$加变量名,即:$PARAM_NAME,不会转换成变量的值。)
更高级的数值条件:(())
val++ | |
val-- | |
++val | |
--val | |
! | 非 |
~ | 按位非 |
** | 幂 |
<< | |
>> | |
& | 按位与 |
| | 按位或 |
&& | 逻辑与 |
|| | 逻辑或 |
测试过程中,发现,还支持很多操作:==,!=,<,>,<=,>=,+,-,*,/.
此外,(())不需要转义以及空格!!!
11.6 管道
可以将一个命令的输出作为另一个命令的输入。可以用重定向来实现,也可以用管道。
管道连接(piping):直接将命令输出重定向到另一个命令中。
格式: command1 | command2
这两个命令不是依次执行的,而是同时运行的,在内部将它们连接起来。
可以在一条命令中使用多条管道,可以持续的将命令的输出通过管道传给其他命令来细化操作。
注意:管道与重定向的区别
(1) | 左边的命令应该有标准输出,右边应该接受标准输入
(2)重定向, > 右边只能是文件, 左边命令要有标准输出
< 左边能接受标准输入,右边只能是文件(文件好像有点不合理)
(3)重定向是在一个进程内执行的,管道触发两个子进程执行|两边的程序
例子:
$cat test2 | grep –n ‘echo’ // 左边输出,右边接受输入,查找包含 grep的行
$grep –n ‘echo’ < test // 效果更上面类似
下面是网上别人的:
Linux Shell常用技巧(十) 管道组合
二十. 通过管道组合Shell命令获取系统运行数据:
1. 输出当前系统中占用内存最多的5条命令:
#1) 通过ps命令列出当前主机正在运行的所有进程。
#2) 按照第五个字段基于数值的形式进行正常排序(由小到大)。
#3) 仅显示最后5条输出。
/> ps aux | sort -k 5n | tail -5
stephen 1861 0.2 2.0 96972 21596 ? S Nov11 2:24 nautilus
stephen 1892 0.0 0.4 102108 4508 ? S<sl Nov11 0:00 /usr/bin/pulseaudio
stephen 1874 0.0 0.9 107648 10124 ? S Nov11 0:00 gnome-volume
stephen 1855 0.0 1.2 123776 13112 ? Sl Nov11 0:00 metacity
stephen 1831 0.0 0.9 125432 9768 ? Ssl Nov11 0:05 /usr/libexec/gnome
2. 找出cpu利用率高的20个进程:
#1) 通过ps命令输出所有进程的数据,-o选项后面的字段列表列出了结果中需要包含的数据列。
#2) 将ps输出的Title行去掉,grep -v PID表示不包含PID的行。
#3) 基于第一个域字段排序,即pcpu。n表示以数值的形式排序。
#4) 输出按cpu使用率排序后的最后20行,即占用率最高的20行。
/> ps -e -o pcpu,pid,user,sgi_p,cmd | grep -v PID | sort -k 1n | tail -20
3. 获取当前系统物理内存的总大小:
#1) 以兆(MB)为单位输出系统当前的内存使用状况。
#2) 通过grep定位到Mem行,该行是以操作系统为视角统计数据的。
#3) 通过awk打印出该行的第二列,即total列。
/> free -m | grep "Mem" | awk '{print $2, "MB"}'
1007 MB
1. 获取当前或指定目录下子目录所占用的磁盘空间,并将结果按照从大到小的顺序输出:
#1) 输出/usr的子目录所占用的磁盘空间。
#2) 以数值的方式倒排后输出。
/> du -s /usr/* | sort -nr
1443980 /usr/share
793260 /usr/lib
217584 /usr/bin
128624 /usr/include
60748 /usr/libexec
45148 /usr/src
21096 /usr/sbin
6896 /usr/local
4 /usr/games
4 /usr/etc
0 /usr/tmp
2. 批量修改文件名:
#1) find命令找到文件名扩展名为.output的文件。
#2) sed命令中的-e选项表示流编辑动作有多次,第一次是将找到的文件名中相对路径前缀部分去掉,如./aa改为aa。
# 流编辑的第二部分,是将20110311替换为mv & 20110310,其中&表示s命令的被替换部分,这里即源文件名。
# 1表示被替换部分中#的(.*)。
#3) 此时的输出应为
# mv 20110311.output 20110310.output
# mv 20110311abc.output 20110310abc.output
# 最后将上面的输出作为命令交给bash命令去执行,从而将所有20110311*.output改为20110311*.output
/> find ./ -name "*.output" -print | sed -e 's/.///g' -e 's/20110311(.*)/mv & 201103101/g' | bash
3. 统计当前目录下文件和目录的数量:
#1) ls -l命令列出文件和目录的详细信息。
#2) ls -l输出的详细列表中的第一个域字段是文件或目录的权限属性部分,如果权限属性部分的第一个字符为d,
# 该文件为目录,如果是-,该文件为普通文件。
#3) 通过wc计算grep过滤后的行数。
/> ls -l * | grep "^-" | wc -l
/> ls -l * | grep "^d" | wc -l
4. 杀掉指定终端的所有进程:
#1) 通过ps命令输出终端为pts/1的所有进程。
#2) 将ps的输出传给grep,grep将过滤掉ps输出的Title部分,-v PID表示不包含PID的行。
#3) awk打印输出grep查找结果的第一个字段,即pid字段。
#4) 上面的三个组合命令是在反引号内被执行的,并将执行的结果赋值给数组变量${K}。
#5) kill方法将杀掉数组${K}包含的pid。
/> kill -9 ${K}=`ps -t pts/1 | grep -v PID | awk '{print $1}'`
5. 将查找到的文件打包并copy到指定目录:
#1) 通过find找到当前目录下(包含所有子目录)的所有*.txt文件。
#2) tar命令将find找到的结果压缩成test.tar压缩包文件。
#3) 如果&&左侧括号内的命令正常完成,则可以执行&&右侧的shell命令了。
#4) 将生成后的test.tar文件copy到/home/.目录下。
/> (find . -name "*.txt" | xargs tar -cvf test.tar) && cp -f test.tar /home/.
#1) cpio从find的结果中读取文件名,将其打包压缩后发送到./dest/dir(目标目录)。
#2) cpio的选项介绍:
# -d:创建需要的目录。
# -a:重置源文件的访问时间。
# -m:保护新文件的修改时间。
# -p:将cpio设置为copy pass-through模式。
/> find . -name "*" | cpio -dampv ./dest/dir
- 使用变量:
shell脚本会自动决定变量值的数据类型
1.4.1 echo “$HOME” (结果:/home/xiongguoan)
更高级的字符串条件:[[]](20章)
高级功能:regex,
11.7 执行数学运算
有两种途径:
Linux中变量分为环境变量和用户变量两种。环境变量就是系统环境中自带的变量,比如set命令可以查看所有的环境变量。用户变量就是用户自己定义的变量,只存在于当前的shell中。
引用一个变量值的时候需要使用美元符,但是引用变量来进行复制的时候不需要美元符。
没有美元符,shell会将其解释为文本字符串
1.5 `` 倒引号。命令替换。在倒引号内部的shell命令首先被执行,其结果输出代替用倒引号括起来的文本,不过特殊字符会被shell解释。
更高级的条件结构:case
case variable in
pattern1 | pattern2 ) commands1 ;;
pattern3 ) commands2 ;;
*) default commands ;;
esac
11.7.1 expr 命令:允许在命令行上处理数学表达式
对于那些容易被shell错误解释的字符,在它们传入expr命令之前需要使用转义字符将其标出来。
比如:
#!/bin/bash
# expr test:
var1=10
var2=20
var3=$(expr $var2 / $var1)
#var4=$(expr $var2 $var1) Error,*
var4=$(expr $var2 \ $var1)*
echo The var3 result is $var3
echo The var4 result is $var4
有一个expr命令操作符表可以看一下。
在脚本文件中引用变量的时候要用美元符:$,。比如:
反引号允许将shell命令输出赋给变量
1.5.1 echo ‘$HOME’ (结果:$HOME)
更多的结构化:for
for var in list
do
commands
done
上面所说的list,其实可以是字符串(每个项以空格分开,如果想避免项中有空格,则可以为每个项加一对引号,如果同时存在引号,最好转义,用另一种引号次之)。
看来,这个for用着还是没有编程语言的方便,如果想执行100次某些命令,那么需要生成一个具有100项的列表。
for star in $(ls)
do
echo "111 $star"
done
11.7.2 使用方括号
比expr方便多了。还不同担心乘号或其它符号。
在shell脚本中进行算数运算会有一个主要的限制:只支持整数运算
比如:
#!/bin/bash
# expr test:
var1=10
var2=20
var3=$[$var2 / $var1]
var4=$[$var2 $var1]*
var5=$[$var2 + $var2 $var1]*
echo The var3 result is $var3
echo The var4 result is $var4
echo The var5 result is $var5
#!/bin/bash
testing=`date`
date +%y%m%d
110131
就算是这样
testing=date
$testing就会直接运行date命令```
###输出重定向
1.6 斜杠。用来去掉在shell解释中字符的特殊含义。在文本中,跟在后面的一个字符不会被shell特殊解释,但其余的不受影响。
11.7.3 浮点解决方案
有几种解决方案,最常见的是用内建的bash计算机,叫做bc
1.bc的基本用法
bash计算机实际上是一种编程语言,它允许在命令行中输入浮点表达式,然后解释并计算表达式
直接输入bc,进入计算机:
Bash计算机设置好scale后就可以显示小数了。
还支持变量
2.在脚本中使用bc
可以用命令替换运行bc命令,并将输出赋值给一个变量
格式如下:
Variable=$(echo “options; expression” | bc)
比如:
#!/bin/bash
var=$(echo "scale=4; 13 / 10" | bc)
echo var is $var
var1=300
var2=45
var3=$(echo "scale=4; $var1 / $var2" | bc)
echo var3 is $var3
var4=$(echo "scale=4; $var3 + $var2 2" | bc)*
echo var4 is $var4
上面的方法适用于较短的运算,涉及到很多数字时就会有点麻烦。
解决方案:bc命令能识别输入重定向,允许将一个文件重定向到bc命令来处理。最好的方案是使用内联输入重定向,它允许你直接在命令中重定向数据。
Varible=$(bc << EOF
Options
Statements
Expressions
EOF
)
比如:
#!/bin/bash
var1=10
var2=9
var3=8
var4=7
var5=$(bc << EOF
scale = 4
a1 = ($var1 $var2)*
a2 = ($var3 $var4)*
a2 + a1 a1*
a2
EOF
)
echo var4 is $var5
EOF标识了内联重定向数据的起止,记住,仍然需要命令替换符号将bc命令的输出赋给变量
将选项和表达式放在脚本的不同行可以让处理过程变得清晰。
还可以在bash计算机中赋值给变量,在bc计算机中创建的变量只在bc计算机中有效,不能再shell脚本中使用
echo "UID id : $UID"
command > outputfile
>会覆盖已有的文件
1.7 []中括号, 主要是用来测试条件的,通常放在if语句的后面。 (不过还是不太明白),但是中括号本身不会在测试语句执行后消失。
11.8 退出脚本
Shell中运行的每个命令都使用退出吗告诉shell它已经运行完毕。
退出码是一个0 – 255的整数值。
定义用户变量的时候不能出现空格:var=100
>>来追加数据
1.7.1 echo [$HOME] (结果:出现错误)
11.8.1 查看退出状态码
如何查看:echo &?
惯例是一个成功结束的命令的退出码是0,如果一个命令结束时有错误,退出状态就是正整数。
- 反引号
输入重定向
<
命令总是在左侧,重定向符号指向数据流动的方向,表示从输入文件流向命令
wc < test6
1.7.2 echo [$HOME ] (结果:[/home/xiongguoan ]) (注意:HOME后面有空格哦。)
11.8.2 exit命令
默认情况下,shell脚本会以脚本中的最后一个命令的退出状态码退出。
也可以改变这种行为
这么写: exit 5
再在终端中查看一下:
Linux中的反引号可以将shell命令的输出赋值给变量:
内联输入重定向<<
指定一个文本标记来划分要输入数据的开始和结尾
1.7.3 echo [$HOME –eq ‘/xiong’] (结果:[/home/xiongguoan –eq /xiong])
补充:关于内联重定向
基本形式如下:
command << delimiter
* document*
delimiter
作用:将两个delimiter之间的内容(document)作为输入传递给command。
主要用途:用于脚本命令行交互
注意:结尾的delimiter要顶格写,前面不能有字符。
例子1:
#!/bin/bash
cat << EOF
hahaha1
hahaha2
hahaha3
EOF
echo exit code is $?
这个不大好理解
#!/bin/bash
command << marker
data
marker
test=`date`
比如这样
wc << EOF
test string 1
test string 2
test string 3
EOF
1.8 {}大括号,主要是和$符号配合,作为字符串连接来使用
echo $test
取代将命令的输出重定向到文件,可以重定向输出到另一个命令,这个过程是管道连接
1.8.1 echo ${HOME}ismydir (结果:/home/xiongguoanismydir)
- 重定向输入输出
command1 | command2
Linux系统其实会同时运行这两个命令,系统内部连接起来,第一个命令产生输出的同时,输出会立即被送到第二个命令,传输数据不会用到任何中间文件和缓冲区域
输出:将命令执行的结果输出到文件中保存
管道最流行的用法是将命令产生的长输出结果通过管道传送给more命令
对ls命令非常普遍,可以强制在每屏数据的末尾停下来
ls -l | more```
2 预定义的变量
输入:将文件输入给命令使用
执行数学运算
2.1 特殊变量
重定向输出使用大于号:>
使用expr命令
expr 1 + 5
expr也可以识别其他的操作符
如> < | & <= >= = != + - * / %
index length
expr 5 * 2
将星号转义,因为*表示通配符
要在shell脚本中将一个数学算式的结果赋给一个变量,需要反引号来获取expr命令的输出
var3=`expr $var2 / $var1`
或者var3=$(expr $var2 / $var1)```
###执行数学表达式更简单的方法
$[ operation ]
var1=$[ 1 + 5 ]
echo $var1
并且不用误解乘号
var2=$[ $var1 * 2 ]
bash shell只支持整数运算```
退出脚本
退出状态码,命令结束运行的时候传给shell,捕获这个值并且在脚本中使用
$? 成功的时候为0
exit命令
shell脚本会以脚本中最后一个命令的退出状态码退出
exit可以指定一个退出状态码
重定向输入使用小于号:<
$ shell变量名的开始,如$var
#!/bin/bash
| 管道,将标准输出转到下一个命令的标准输入
date > test6
$# 记录传递给Shell的自变量个数
test6<wc
# 注释开始
- 管道
& 在后台执行一个进程
管道是将一个命令的输出作为下一个命令的输入,比如:
? 匹配一个字符
#!/bin/bash
* 匹配0到多个字符(与DOS不同,可在文件名中间使用,并且含.)
set | more
$- 使用set及执行时传递给shell的标志位
- 数学运算
$! 最后一个子进程的进程号
Linux shell中使用expr作为整数的运算,使用bc进行浮点数的运算,比如:
$? 取最近一次命令执行后的退出状态(返回码)
#!/bin/bash
$* 传递给shell script的参数
test1=`expr 1 * 5`
$@ 所有参数,个别的用双引号括起来
echo $test1
$0 当前shell的名字
var1=`echo " scale=4; 3.44 / 5" |bc`
$n (n:1-) 位置参数
echo $var1
$$ 进程标识号(Process Identifier Number, PID)
- 退出脚本
> 输出重定向
#!/bin/bash
< 输入重定向
exit 5
>> 输出重定向(追加方式)
[] 列出字符变化范围,如[a-z]
技能树.IT修真院
“我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,掌控自己学习的节奏,学习的路上不再迷茫”。
这里是技能树.IT修真院,成千上万的师兄在这里找到了自己的学习路线,学习透明化,成长可见化,师兄1对1免费指导。快来与我一起学习吧 !
2.2 代值变量
注册邀请码:99872160 注册链接:IT修真院
* 任意字符串
? 一个任意字符
[abc] a, b, c三者中之一
[a-n] 从a到n的任一字符
2.3 特殊字符的表达
b 退回
c 打印一行时没有换行符 这个我们经常会用到
f 换页
r 回车
t 制表
v 垂直制表
\ 反斜线本身
2.4 其他字符
2.4.1 分号
; 表示一行结束
2.4.2 圆括号
() 表示在新的子shell中执行括号内的命令(这样可以不改变当前shell的状态。)
但是圆括号在单/双引号内失去作用,只作为普通字符。
2.4.3 花括号
2.4.3.1 分割命令的用法
与圆括号相似,但是:1. 花括号内的命令在当前shell中执行;2.花括号必须作为命令的第一个字符出现。
2.4.3.2 引用变量的用法
在$后面,表示变量名的开始和结束
2.4.4 方括号
相当与test命令,用来执行测试条件,通常用在需要判断条件的语句后面,例如:if,while等等。
3 设置变量
3.1 格式:VARNAME=value (i.e. PARAM=’hello’)
3.2 注意:
3.2.1 等号的前后不能有空格
3.2.2 如果变量的值是一个命令的执行结果,请加上反引号(`)。
4 引用变量
4.1 $VARNAME
4.1.1 e.i. echo $HOME (结果:/home/xiongguoan)
4.2 变量默认值
4.2.1 在引用一个变量的时候可以设定默认值。如果在此之前,该变量已经设定了值,则此默认值无效。如果此时变量没有被设定值,则使用此默认值(但是没有改变此变量的值)。
4.2.2 echo Hello ${UNAME:-there} #其中there是UNAME的默认值
4.2.3 其他关于默认值与判读变量的方法:
利用大括号表示变量替换
表示形式 |
说明 |
${VARIABLE} |
基本变量替换。大括号限定变量名的开始和结束 |
${VARIABLE:-DEFAULT} |
如果VARIABLE没有值,则这种表示形式返回DEFAULT的值 |
${VARIABLE:=DEFAULT} |
如果VARIABLE没有值,则这种表达形式返回DEFAULT的值。另外,如果VARIABLE没有设置,则把DEFAULT的值赋予它 |
${VARIABLE:+VALUE} |
如果VARIABLE被设置,则这种表示形式返回VALUE;否则,返回一个空串 |
${# VARIABLE} |
这种表示形式返回VARIABLE值的长度,除非VARIABLE是* 或者@在为*或者@的特殊情况下,则返回$@所表示的元素的个数。要记住,$ @保存传给该脚本的参数清单 |
${VARIABLE:?MESSAGE} |
如果VARIABLE没有值,则这种表示形式返回MESSAGE的值。Shell也显示出VARIABLE的名字,所以这种形式对捕获得错误很有用 |
4.2.4 注意:
4.2.4.1 使用${VALIABLE:?MESSAGE},如果发现此变量此时没有值,则脚本停止运行并显示行号和变量名称。 主要用于调试。
4.2.4.2
5 位置变量
5.1 使用$1,$2,$3…$9,${10},${11}…来代表输入的参数。其中$0代表被执行的命令或者脚本的名字。$1,$2…代表输入的第1,2…个参数
5.2 例子:
# cat count.sh#!/bin/sh
A=$1 # 将位置$1的数值读入,并赋给变量A
B=$2 # 将位置$2的数值读入,并赋给变量B
C=$[$A+$B] # 将变量A与B的值相加,将结果赋给C
echo $C # 显示C的数值
结果:
# ./count.sh 3 6
9
# ./count.sh 34 28
62
5.3 $@和$*代表参数的列表,$#代表参数的数量 (不知道$@和$*之间的差别)
6 运算符和优先级
本文由美高梅赌堵59599发布于美高梅-操作系统,转载请注明出处:Linux中变量分为环境变量和用户变量两种,Shell可以让你将多个命令串起来
关键词: