#!/bin/bash #涉及到的命令:#! whereis cd pwd echo export env unset source #!指定解释器的位置,此处用/bin/bash作为解释器 whereis bash #输出bash解释器的位置 cd ./ #改变工作空间 改变环境变量 $PWD pwd #查看当前工作空间路径 相当与 echo $PWD #自建命令与外部命令: #自建命令是SHELL内置命令:以上基本都是自建命令 #外部命令是一个可执行程序,如find grep 和本例 bash.sh,外部命令执行时会申请子进程,子进程执行完毕后回到父进程继续执行,进入子进程后会拷贝父进程的环境变量,但在子进程中无法通过改变环境变量影响到父进程的环境变量,因此简单的说只有内建命令才能改变环境变量。 export HOME=/etc/ #改变环境变量HOME的值 env -i PATH=./:$PATH bash.sh #-i忽略所有的环境变量,紧接着后面设置新的环境变量PATH,然后运行文件bash.sh #-u可忽略制定的环境变量 source ./bash.sh #行为模式运行文件,行为模式中遇到外部命令不会新建子进程,而是在当前进程执行外部命令。 a=1 unset a #让a成为空,-f 标记可以让方法成为空
【shell 脚本参数】
$0 - $9 : $0为脚本名,$1 - $9 为参数1 到 9
$* : 以一个字符串显示所以参数
$@:可用于迭代参数的变量,直接打印与$*样子一样
$#: 除开$0 的参数个数
shift :删除参数1,其后的参数左移一位
mv:移动或重命名文件或目录,通常跟 参数 i ,否则容易覆盖掉已有的文件
【管道与重定向】
交互命令行中的标准输入 标准输出 标准错误:
标准输入 和 标准输出都是终端, 标准错误是当命令出错的时候终端显示的内容。
重定向:可以用 "<" 改变标准输入 ">" 或 ">>" 改变标准输出
echo "redirect to file" > ./temp.txt #终端不会成为标准输出,redirect to file会被输出到文件中,文件的原始数据被清空,只保留新的数据。
echo "redirect to file" >> ./temp.txt #跟>>差不多,只不过是追加数据,即保留原始数据。
cat < ./temp.txt > temp_out.txt #会将temp.txt中的内容拷贝并覆盖 temp_out.txt的内容。
cat:链接或显示文件, cat File 可将file中的内容输出到标准输出。
管道:符号 | 表示管道,管道可以将 "|" 左边的输出作为 "|" 右边的输入
ps -ef | grep "nginx" #打印nginx进程的信息
head -n10 ./temp.txt | grep "redirect"
ps:列举所有当前运行进程的信息
grep: 查询输入中匹配的字符串并打印出对应的一行
head:显示一个文件或多个文件的前几行或前几个字节
【特殊文件】
/dev/null : 凡是向该文件进行的标准输出都将作废,凡是将该文作为标准输入的标准输出都将变为空。
/dev/zero: 输入输出均变为0, 大小不变。
/dev/tty : 若将该文件作为标准输出,则输出会显示到终端显示器上。
read: 读取标准输入中的一行
【变量】
shell属于弱类型语言
字符串+整型 = 字符串
null + 整形 = 整形
这里考虑如下代码:
a="123abc" let " a = $a + 1" echo $a
按照以往的习惯可能会认为 输出为1或者124,不过shell 可能观察到第一个数为数字,然后会将整行包括 abc 全部当成数字来处理,而默认进制是 10 进制,所以abc无法被识别,会提示 “value too great for base” , 解决方法是在前面加上 14#123abc ,这标识 123abc是14进制的数,所以abc没有超过base,但这样明显违背了coder的本意,所以应尽量避免这种情况。
变量的真面目:
通常写的$a,其实际上是${a}的简写。完整的形式实际上还提供了更多的实用功能,如替换和模式匹配
替换:
${varname:-word} :如果varname存在且非null,则返回varname的值,否则返回word
${varname:=word} :如果varname存在且非null,则返回varname的值,否则将varname赋值为word,并返回值
${varname:?message} :如果varname存在且非null,则返回varname的值,否则打印message并exit
${varname:+word} : 如果varname存在且非null,则返回word,否则返回null.
模式匹配:
${varname#pattern} : 从开头开始匹配最短的并删除,返回剩下的。
${varname##pattern} : 从开头开始匹配最长的并删除,返回剩下的。
${varname%pattern} : 从结尾开始匹配最短的并删除,返回剩下的。
${varname%%pattern} : 从结尾开始匹配最长的并删除,返回剩下的。
${varname/pattern/string}: 匹配最长的并替换为string,只替换第一个。
${varname//pattern/string}: 匹配最长的并替换为string,替换全部匹配。
【方法】
格式
function funcname() { echo "your input is $@" exit 0 }
方法的参数不用显示给出,方法中用$1 - $9 或者其他方法调用参数,exit会直接推出程序,return推出方法。
调用直接写方法名,空格后加参数: funcname param1 param2 ...
包含文件用 source filepath+filename
【流程控制】
下面是一段处理参数代码,基本用到了所有的流程控制语句。
while [ ! $# = 0 ] do case $1 in -f) if [ ! $2 = "" ] then echo "after -f is $2" shift 2 else echo "you should put a value after -f" shift fi ;; -d) if [ ! $2 = "" ] then echo "after -d is $2" shift 2 else echo "you should put -d value after -d" shift 1 fi ;; *) echo "invalid input $1" shift ;; esac done
【正则】
字符集:
[:alnum:] // 意思是 alpha + number 等于 [0-9a-zA-Z]
[:alpha:] //字母
[:blank:] //空格和tab
[:digit:] //数字字符
......
呃,没什么好写的了呢..
【文本处理】
先看命令:
sort : 排序文本,并且,可以通过修改参数按照规则对字段排序。
uniq : 将文本中重复的记录去除,并且可以显示重复的情况。
wc : 统计文本出现的行数,字数以及字符书。
pr 、fmt、fold : 格式化文本输出 , 主要用于处理段落式文本。
head/tail : 分别提取文本的开头和结尾
cut/join : 字段处理,可以对字段进行取出和拼接操作。
tr : 完成简单的文本替换。
sort: 行排序
几个重要标记:
-d 设置字典序,忽略以特殊字符开头的行
-n 整数序列
-f 忽略大小写
-u 合并相同行
-t[String] 指定分割符
-k[Number] 指定依照哪一列排序 -t -k连用
uniq: 去重或显示重复信息
-c 在输出行前面加上在输入文件中出现的次数。
-d 仅输出重复行
-u 仅输出不重复行
wc: 统计
-c 显示字符个数
-w 显示单词个数
-l 显示文本行数
fmt / fold
-w 限制文本宽度
head 取开头
-n[number] 指定从开头取的行数
-c[number] 指定从开头取的字节数
cut 取字段
-d [string] 指定分割符
-f [number,number.....] 指定获取字段列
join 连接字段
-1 [number] 指定以第一个文件哪一列来合并
-2 [number] 指定以第二个文件哪一列来合并
-a[number] 保留number列所有数据,只加入新的数据,有点类似sql中的left join right join
tr 字符替换或删除
-s 用string2 替换一个或多个连续的string1
【文件操作】
权限:
ls ~
大概会出现如下信息:
drwxr-xr-x 5 louis louis 4096 2012-09-15 15:48 Downloads drwxrwxr-x 3 louis louis 4096 2012-04-18 20:11 eclipse -rw-r--r-- 1 louis louis 179 2012-04-10 17:13 examples.desktop -rw-rw-r-- 1 louis louis 45819 2012-09-15 13:24 gdq.jpg
从左到右依次是:文件类型&权限位,链接数,所有者,所有者群组,文件大小,修改时间,文件名
文件类型 : d为目录,-为普通文件,d为,l符号链接文件,b块文件等等
权限位: linux权限位有9位,比如Downloads的权限为 rwxr-xr-x ,最开始的rwx为文件创建人的权限,中间的r-x为创建人所在用户组的权限,最后三位r-x为其他用户的权限。
把字符全部替换为1,-替换为0,则得到一个二进制数 111101101,替换成10进制则是755,改权限可以不用写9位字母而直接写十进制就行了。
所有者和所有者群组:所有者为创建人,群组即所有者所在的群,通过chown可以改变所有者,chgrp改变群组,chmod改变9位权限位
文件操作:
touch可以修改文件修改时间
find + xargs 可以用户文件遍历和对文件的批量操作,下面是find的几个例子:
find /etc -name "*rc" -print #递归找出etc目录下所有文件名最后两个字母为rc的文件
find -perm 777 /etc #递归找etc目录下权限为777的文件
find ~ -type d -print #递归找home目录下的目录文件
find /tmp -newer /tmp/record.txt ! /tmp/login.txt #递归找比record.txt文件新且比login.txt旧的文件
find ~ -name "*sh" | xargx grep "function" #找home 文件下的所用sh文件,并用他们作为标准输入执行grep指令。
comm,diff 和 vimdiff 比较两个文件的异同。有点像svn。
【sed】
-n 按指示打印
-e [string] 命令
命令中 p 打印, d 隐藏 , s/string/replacement/
一些例子:
ll | sed -n -e '/-09-/s/-09-/-08-/p' | sed -n -e 's/[[:blank:]]\+/ /gp'
这里把文件中的创建日期的月份改为08 , 并删除多余的空格,只保留一个空格。
浙公网安备 33010602011771号